@memberjunction/ng-core-entity-forms 5.42.0 → 5.44.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.
- package/dist/__tests__/model-prediction.logic.test.d.ts +2 -0
- package/dist/__tests__/model-prediction.logic.test.d.ts.map +1 -0
- package/dist/__tests__/model-prediction.logic.test.js +140 -0
- package/dist/__tests__/model-prediction.logic.test.js.map +1 -0
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js +79 -105
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js +7 -10
- package/dist/lib/custom/AIAgents/FlowAgentType/flow-agent-form-section.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +46 -51
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +2 -0
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +300 -378
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +22 -29
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +15 -17
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +27 -34
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +11 -0
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +48 -47
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +438 -454
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +48 -51
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +253 -282
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +24 -33
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +263 -311
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts +6 -0
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +475 -493
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +122 -173
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +190 -248
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +19 -23
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +16 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js +54 -0
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -0
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js +23 -24
- package/dist/lib/custom/SearchScopes/searchscopeprovider-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +25 -46
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +100 -130
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +187 -205
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +8 -0
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +412 -489
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +100 -126
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +166 -184
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +42 -61
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +8 -17
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +0 -2
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +183 -188
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +108 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +665 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +94 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +257 -0
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +38 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +200 -0
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +44 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +180 -0
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +12 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +46 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +64 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +267 -0
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +53 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +111 -0
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +42 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +193 -0
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -0
- package/dist/lib/custom/custom-forms.module.d.ts +58 -49
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +64 -16
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +2 -0
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +25 -25
- package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js +280 -216
- package/dist/lib/generated/Entities/MJAIAgent/mjaiagent.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js +25 -21
- package/dist/lib/generated/Entities/MJAIAgentChannel/mjaiagentchannel.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js +68 -14
- package/dist/lib/generated/Entities/MJAIAgentRun/mjaiagentrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js +44 -32
- package/dist/lib/generated/Entities/MJAIAgentSession/mjaiagentsession.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js +66 -0
- package/dist/lib/generated/Entities/MJAIAgentSkill/mjaiagentskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +55 -19
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +28 -10
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js +167 -0
- package/dist/lib/generated/Entities/MJAISkill/mjaiskill.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillAction/mjaiskillaction.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js +82 -0
- package/dist/lib/generated/Entities/MJAISkillPermission/mjaiskillpermission.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js +64 -0
- package/dist/lib/generated/Entities/MJAISkillSubAgent/mjaiskillsubagent.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js +35 -17
- package/dist/lib/generated/Entities/MJAction/mjaction.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js +59 -51
- package/dist/lib/generated/Entities/MJApplication/mjapplication.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js +25 -7
- package/dist/lib/generated/Entities/MJCollection/mjcollection.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js +11 -7
- package/dist/lib/generated/Entities/MJCollectionArtifact/mjcollectionartifact.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js +56 -46
- package/dist/lib/generated/Entities/MJConversation/mjconversation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js +73 -59
- package/dist/lib/generated/Entities/MJConversationDetail/mjconversationdetail.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js +24 -4
- package/dist/lib/generated/Entities/MJDuplicateRunDetailMatch/mjduplicaterundetailmatch.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +137 -87
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityActionInvocation/mjentityactioninvocation.form.component.js +10 -8
- package/dist/lib/generated/Entities/MJEntityActionInvocation/mjentityactioninvocation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js +47 -29
- package/dist/lib/generated/Entities/MJEntityDocument/mjentitydocument.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js +99 -0
- package/dist/lib/generated/Entities/MJExperiment/mjexperiment.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js +101 -0
- package/dist/lib/generated/Entities/MJExperimentSession/mjexperimentsession.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js +115 -0
- package/dist/lib/generated/Entities/MJExperimentSessionIteration/mjexperimentsessioniteration.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js +63 -9
- package/dist/lib/generated/Entities/MJFile/mjfile.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js +32 -14
- package/dist/lib/generated/Entities/MJFileStorageProvider/mjfilestorageprovider.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js +161 -0
- package/dist/lib/generated/Entities/MJMLAlgorithm/mjmlalgorithm.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js +89 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCase/mjmlalgorithmusecase.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js +76 -0
- package/dist/lib/generated/Entities/MJMLAlgorithmUseCaseRanking/mjmlalgorithmusecaseranking.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js +141 -0
- package/dist/lib/generated/Entities/MJMLModel/mjmlmodel.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js +88 -0
- package/dist/lib/generated/Entities/MJMLModelScoringBinding/mjmlmodelscoringbinding.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js +143 -0
- package/dist/lib/generated/Entities/MJMLTrainingPipeline/mjmltrainingpipeline.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js +110 -0
- package/dist/lib/generated/Entities/MJMLTrainingRun/mjmltrainingrun.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js +56 -24
- package/dist/lib/generated/Entities/MJOpenApp/mjopenapp.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +19 -17
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +46 -26
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRemoteOperation/mjremoteoperation.form.component.js +12 -6
- package/dist/lib/generated/Entities/MJRemoteOperation/mjremoteoperation.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js +36 -18
- package/dist/lib/generated/Entities/MJRole/mjrole.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js +8 -6
- package/dist/lib/generated/Entities/MJSchemaInfo/mjschemainfo.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js +78 -0
- package/dist/lib/generated/Entities/MJScopedPromptPart/mjscopedpromptpart.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +145 -109
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/generated-forms.module.d.ts +356 -335
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +304 -226
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js +44 -44
- package/dist/lib/panels/ai-agents/agent-realtime.panel.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +43 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +240 -0
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +69 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js +130 -0
- package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +83 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +293 -0
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -0
- package/package.json +38 -36
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts +0 -82
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.d.ts.map +0 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js +0 -1033
- package/dist/lib/custom/ai-agent-run/ai-agent-run-visualization.component.js.map +0 -1
|
@@ -510,9 +510,9 @@ function MJTestSuiteRunFormComponentExtended_Conditional_129_Template(rf, ctx) {
|
|
|
510
510
|
} }
|
|
511
511
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
512
512
|
const _r13 = i0.ɵɵgetCurrentView();
|
|
513
|
-
i0.ɵɵelementStart(0, "button",
|
|
513
|
+
i0.ɵɵelementStart(0, "button", 154);
|
|
514
514
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_4_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Passed")); });
|
|
515
|
-
i0.ɵɵelement(1, "i",
|
|
515
|
+
i0.ɵɵelement(1, "i", 155);
|
|
516
516
|
i0.ɵɵtext(2);
|
|
517
517
|
i0.ɵɵelementEnd();
|
|
518
518
|
} if (rf & 2) {
|
|
@@ -523,7 +523,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Condi
|
|
|
523
523
|
} }
|
|
524
524
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
525
525
|
const _r14 = i0.ɵɵgetCurrentView();
|
|
526
|
-
i0.ɵɵelementStart(0, "button",
|
|
526
|
+
i0.ɵɵelementStart(0, "button", 156);
|
|
527
527
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Failed")); });
|
|
528
528
|
i0.ɵɵelement(1, "i", 93);
|
|
529
529
|
i0.ɵɵtext(2);
|
|
@@ -536,9 +536,9 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Condi
|
|
|
536
536
|
} }
|
|
537
537
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
538
538
|
const _r15 = i0.ɵɵgetCurrentView();
|
|
539
|
-
i0.ɵɵelementStart(0, "button",
|
|
539
|
+
i0.ɵɵelementStart(0, "button", 157);
|
|
540
540
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_6_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter("Error")); });
|
|
541
|
-
i0.ɵɵelement(1, "i",
|
|
541
|
+
i0.ɵɵelement(1, "i", 158);
|
|
542
542
|
i0.ɵɵtext(2);
|
|
543
543
|
i0.ɵɵelementEnd();
|
|
544
544
|
} if (rf & 2) {
|
|
@@ -549,17 +549,17 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Condi
|
|
|
549
549
|
} }
|
|
550
550
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
551
551
|
const _r12 = i0.ɵɵgetCurrentView();
|
|
552
|
-
i0.ɵɵelementStart(0, "div", 141)(1, "div",
|
|
552
|
+
i0.ɵɵelementStart(0, "div", 141)(1, "div", 146)(2, "button", 147);
|
|
553
553
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter(null)); });
|
|
554
554
|
i0.ɵɵtext(3);
|
|
555
555
|
i0.ɵɵelementEnd();
|
|
556
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_4_Template, 3, 3, "button",
|
|
557
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_5_Template, 3, 3, "button",
|
|
558
|
-
i0.ɵɵconditionalCreate(6, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_6_Template, 3, 3, "button",
|
|
556
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_4_Template, 3, 3, "button", 148);
|
|
557
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_5_Template, 3, 3, "button", 149);
|
|
558
|
+
i0.ɵɵconditionalCreate(6, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Conditional_6_Template, 3, 3, "button", 150);
|
|
559
559
|
i0.ɵɵelementEnd();
|
|
560
|
-
i0.ɵɵelementStart(7, "div",
|
|
560
|
+
i0.ɵɵelementStart(7, "div", 151)(8, "button", 152);
|
|
561
561
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.exportToCSV()); });
|
|
562
|
-
i0.ɵɵelement(9, "i",
|
|
562
|
+
i0.ɵɵelement(9, "i", 153);
|
|
563
563
|
i0.ɵɵtext(10, " Export CSV ");
|
|
564
564
|
i0.ɵɵelementEnd()()();
|
|
565
565
|
} if (rf & 2) {
|
|
@@ -576,22 +576,22 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Templ
|
|
|
576
576
|
i0.ɵɵconditional(ctx_r1.getRunCountByStatus("Error") > 0 ? 6 : -1);
|
|
577
577
|
} }
|
|
578
578
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_2_For_3_Template(rf, ctx) { if (rf & 1) {
|
|
579
|
-
i0.ɵɵelementStart(0, "div",
|
|
580
|
-
i0.ɵɵelement(1, "div",
|
|
581
|
-
i0.ɵɵelementStart(3, "div",
|
|
582
|
-
i0.ɵɵelement(4, "div",
|
|
579
|
+
i0.ɵɵelementStart(0, "div", 160);
|
|
580
|
+
i0.ɵɵelement(1, "div", 161)(2, "div", 162);
|
|
581
|
+
i0.ɵɵelementStart(3, "div", 163);
|
|
582
|
+
i0.ɵɵelement(4, "div", 164)(5, "div", 165);
|
|
583
583
|
i0.ɵɵelementEnd()();
|
|
584
584
|
} }
|
|
585
585
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
586
|
-
i0.ɵɵelementStart(0, "div", 142)(1, "div",
|
|
587
|
-
i0.ɵɵrepeaterCreate(2, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_2_For_3_Template, 6, 0, "div",
|
|
586
|
+
i0.ɵɵelementStart(0, "div", 142)(1, "div", 159);
|
|
587
|
+
i0.ɵɵrepeaterCreate(2, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_2_For_3_Template, 6, 0, "div", 160, i0.ɵɵrepeaterTrackByIdentity);
|
|
588
588
|
i0.ɵɵelementEnd()();
|
|
589
589
|
} if (rf & 2) {
|
|
590
590
|
i0.ɵɵadvance(2);
|
|
591
591
|
i0.ɵɵrepeater(i0.ɵɵpureFunction0(0, _c0));
|
|
592
592
|
} }
|
|
593
593
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_12_Template(rf, ctx) { if (rf & 1) {
|
|
594
|
-
i0.ɵɵelementStart(0, "span",
|
|
594
|
+
i0.ɵɵelementStart(0, "span", 175);
|
|
595
595
|
i0.ɵɵelement(1, "i", 23);
|
|
596
596
|
i0.ɵɵtext(2);
|
|
597
597
|
i0.ɵɵelementEnd();
|
|
@@ -601,7 +601,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
601
601
|
i0.ɵɵtextInterpolate1(" ", run_r17.DurationSeconds.toFixed(1), "s ");
|
|
602
602
|
} }
|
|
603
603
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
604
|
-
i0.ɵɵelementStart(0, "span",
|
|
604
|
+
i0.ɵɵelementStart(0, "span", 176);
|
|
605
605
|
i0.ɵɵelement(1, "i", 28);
|
|
606
606
|
i0.ɵɵtext(2);
|
|
607
607
|
i0.ɵɵelementEnd();
|
|
@@ -611,13 +611,13 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
611
611
|
i0.ɵɵtextInterpolate1(" ", run_r17.CostUSD.toFixed(6), " ");
|
|
612
612
|
} }
|
|
613
613
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
614
|
-
i0.ɵɵelement(0, "mj-entity-link-pill",
|
|
614
|
+
i0.ɵɵelement(0, "mj-entity-link-pill", 177);
|
|
615
615
|
} if (rf & 2) {
|
|
616
616
|
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
617
617
|
i0.ɵɵproperty("entityName", run_r17.TargetLogEntity)("recordId", run_r17.TargetLogID);
|
|
618
618
|
} }
|
|
619
619
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
620
|
-
i0.ɵɵelementStart(0, "span",
|
|
620
|
+
i0.ɵɵelementStart(0, "span", 182);
|
|
621
621
|
i0.ɵɵtext(1);
|
|
622
622
|
i0.ɵɵelementEnd();
|
|
623
623
|
} if (rf & 2) {
|
|
@@ -626,8 +626,8 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
626
626
|
i0.ɵɵtextInterpolate(tag_r18);
|
|
627
627
|
} }
|
|
628
628
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_Template(rf, ctx) { if (rf & 1) {
|
|
629
|
-
i0.ɵɵelementStart(0, "div",
|
|
630
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_For_2_Template, 2, 1, "span",
|
|
629
|
+
i0.ɵɵelementStart(0, "div", 178);
|
|
630
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_For_2_Template, 2, 1, "span", 182, i0.ɵɵrepeaterTrackByIdentity);
|
|
631
631
|
i0.ɵɵelementEnd();
|
|
632
632
|
} if (rf & 2) {
|
|
633
633
|
const run_r17 = i0.ɵɵnextContext().$implicit;
|
|
@@ -637,7 +637,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
637
637
|
} }
|
|
638
638
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template(rf, ctx) { if (rf & 1) {
|
|
639
639
|
const _r20 = i0.ɵɵgetCurrentView();
|
|
640
|
-
i0.ɵɵelementStart(0, "button",
|
|
640
|
+
i0.ɵɵelementStart(0, "button", 199);
|
|
641
641
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template_button_click_0_listener($event) { const num_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); ctx_r1.setInlineRating(num_r21); return i0.ɵɵresetView($event.stopPropagation()); })("mouseenter", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template_button_mouseenter_0_listener() { const num_r21 = i0.ɵɵrestoreView(_r20).$implicit; const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.inlineHoverRating = num_r21); })("mouseleave", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template_button_mouseleave_0_listener() { i0.ɵɵrestoreView(_r20); const ctx_r1 = i0.ɵɵnextContext(5); return i0.ɵɵresetView(ctx_r1.inlineHoverRating = 0); });
|
|
642
642
|
i0.ɵɵtext(1);
|
|
643
643
|
i0.ɵɵelementEnd();
|
|
@@ -649,10 +649,10 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
649
649
|
i0.ɵɵtextInterpolate1(" ", num_r21, " ");
|
|
650
650
|
} }
|
|
651
651
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
652
|
-
i0.ɵɵelementStart(0, "div",
|
|
652
|
+
i0.ɵɵelementStart(0, "div", 189)(1, "span", 200);
|
|
653
653
|
i0.ɵɵtext(2);
|
|
654
654
|
i0.ɵɵelementEnd();
|
|
655
|
-
i0.ɵɵelementStart(3, "span",
|
|
655
|
+
i0.ɵɵelementStart(3, "span", 201);
|
|
656
656
|
i0.ɵɵtext(4);
|
|
657
657
|
i0.ɵɵelementEnd()();
|
|
658
658
|
} if (rf & 2) {
|
|
@@ -664,53 +664,53 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
664
664
|
} }
|
|
665
665
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
666
666
|
const _r19 = i0.ɵɵgetCurrentView();
|
|
667
|
-
i0.ɵɵelementStart(0, "div",
|
|
668
|
-
i0.ɵɵelement(1, "div",
|
|
669
|
-
i0.ɵɵelementStart(2, "div",
|
|
667
|
+
i0.ɵɵelementStart(0, "div", 181);
|
|
668
|
+
i0.ɵɵelement(1, "div", 183);
|
|
669
|
+
i0.ɵɵelementStart(2, "div", 184)(3, "div", 185);
|
|
670
670
|
i0.ɵɵtext(4, "Quick Feedback");
|
|
671
671
|
i0.ɵɵelementEnd();
|
|
672
|
-
i0.ɵɵelementStart(5, "div",
|
|
673
|
-
i0.ɵɵrepeaterCreate(7, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template, 2, 11, "button",
|
|
672
|
+
i0.ɵɵelementStart(5, "div", 186)(6, "div", 187);
|
|
673
|
+
i0.ɵɵrepeaterCreate(7, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_For_8_Template, 2, 11, "button", 188, i0.ɵɵrepeaterTrackByIdentity);
|
|
674
674
|
i0.ɵɵelementEnd();
|
|
675
|
-
i0.ɵɵconditionalCreate(9, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Conditional_9_Template, 5, 2, "div",
|
|
675
|
+
i0.ɵɵconditionalCreate(9, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Conditional_9_Template, 5, 2, "div", 189);
|
|
676
676
|
i0.ɵɵelementEnd();
|
|
677
|
-
i0.ɵɵelementStart(10, "div",
|
|
677
|
+
i0.ɵɵelementStart(10, "div", 190)(11, "span", 191);
|
|
678
678
|
i0.ɵɵtext(12, "Was it correct?");
|
|
679
679
|
i0.ɵɵelementEnd();
|
|
680
|
-
i0.ɵɵelementStart(13, "div",
|
|
680
|
+
i0.ɵɵelementStart(13, "div", 192)(14, "label", 193);
|
|
681
681
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_label_click_14_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
682
|
-
i0.ɵɵelementStart(15, "input",
|
|
682
|
+
i0.ɵɵelementStart(15, "input", 194);
|
|
683
683
|
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_input_ngModelChange_15_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
|
|
684
684
|
i0.ɵɵelementEnd();
|
|
685
685
|
i0.ɵɵelementStart(16, "span");
|
|
686
686
|
i0.ɵɵtext(17, "Yes");
|
|
687
687
|
i0.ɵɵelementEnd()();
|
|
688
|
-
i0.ɵɵelementStart(18, "label",
|
|
688
|
+
i0.ɵɵelementStart(18, "label", 193);
|
|
689
689
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_label_click_18_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
690
|
-
i0.ɵɵelementStart(19, "input",
|
|
690
|
+
i0.ɵɵelementStart(19, "input", 194);
|
|
691
691
|
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_input_ngModelChange_19_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
|
|
692
692
|
i0.ɵɵelementEnd();
|
|
693
693
|
i0.ɵɵelementStart(20, "span");
|
|
694
694
|
i0.ɵɵtext(21, "No");
|
|
695
695
|
i0.ɵɵelementEnd()();
|
|
696
|
-
i0.ɵɵelementStart(22, "label",
|
|
696
|
+
i0.ɵɵelementStart(22, "label", 193);
|
|
697
697
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_label_click_22_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
698
|
-
i0.ɵɵelementStart(23, "input",
|
|
698
|
+
i0.ɵɵelementStart(23, "input", 194);
|
|
699
699
|
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_input_ngModelChange_23_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineIsCorrect, $event) || (ctx_r1.inlineIsCorrect = $event); return i0.ɵɵresetView($event); });
|
|
700
700
|
i0.ɵɵelementEnd();
|
|
701
701
|
i0.ɵɵelementStart(24, "span");
|
|
702
702
|
i0.ɵɵtext(25, "Not Sure");
|
|
703
703
|
i0.ɵɵelementEnd()()()();
|
|
704
|
-
i0.ɵɵelementStart(26, "div",
|
|
704
|
+
i0.ɵɵelementStart(26, "div", 195);
|
|
705
705
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_div_click_26_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
706
|
-
i0.ɵɵelementStart(27, "textarea",
|
|
706
|
+
i0.ɵɵelementStart(27, "textarea", 196);
|
|
707
707
|
i0.ɵɵtwoWayListener("ngModelChange", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_textarea_ngModelChange_27_listener($event) { i0.ɵɵrestoreView(_r19); const ctx_r1 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r1.inlineComments, $event) || (ctx_r1.inlineComments = $event); return i0.ɵɵresetView($event); });
|
|
708
708
|
i0.ɵɵelementEnd()();
|
|
709
|
-
i0.ɵɵelementStart(28, "div",
|
|
709
|
+
i0.ɵɵelementStart(28, "div", 197);
|
|
710
710
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_div_click_28_listener($event) { i0.ɵɵrestoreView(_r19); return i0.ɵɵresetView($event.stopPropagation()); });
|
|
711
|
-
i0.ɵɵelementStart(29, "button",
|
|
711
|
+
i0.ɵɵelementStart(29, "button", 152);
|
|
712
712
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r19); const run_r17 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openTestRun(run_r17.ID)); });
|
|
713
|
-
i0.ɵɵelement(30, "i",
|
|
713
|
+
i0.ɵɵelement(30, "i", 198);
|
|
714
714
|
i0.ɵɵtext(31, " View Full Details ");
|
|
715
715
|
i0.ɵɵelementEnd();
|
|
716
716
|
i0.ɵɵelementStart(32, "button", 89);
|
|
@@ -745,30 +745,30 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
745
745
|
} }
|
|
746
746
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
747
747
|
const _r16 = i0.ɵɵgetCurrentView();
|
|
748
|
-
i0.ɵɵelementStart(0, "div",
|
|
748
|
+
i0.ɵɵelementStart(0, "div", 166)(1, "div", 167);
|
|
749
749
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Template_div_click_1_listener() { const run_r17 = i0.ɵɵrestoreView(_r16).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.toggleRunExpanded(run_r17.ID)); });
|
|
750
|
-
i0.ɵɵelementStart(2, "div",
|
|
750
|
+
i0.ɵɵelementStart(2, "div", 168);
|
|
751
751
|
i0.ɵɵtext(3);
|
|
752
752
|
i0.ɵɵelementEnd();
|
|
753
|
-
i0.ɵɵelementStart(4, "div",
|
|
753
|
+
i0.ɵɵelementStart(4, "div", 169);
|
|
754
754
|
i0.ɵɵelement(5, "i", 11);
|
|
755
755
|
i0.ɵɵelementEnd();
|
|
756
|
-
i0.ɵɵelementStart(6, "div",
|
|
756
|
+
i0.ɵɵelementStart(6, "div", 170)(7, "div", 171)(8, "div", 172);
|
|
757
757
|
i0.ɵɵtext(9);
|
|
758
758
|
i0.ɵɵelementEnd();
|
|
759
|
-
i0.ɵɵelement(10, "app-evaluation-badge",
|
|
759
|
+
i0.ɵɵelement(10, "app-evaluation-badge", 173);
|
|
760
760
|
i0.ɵɵelementEnd();
|
|
761
|
-
i0.ɵɵelementStart(11, "div",
|
|
762
|
-
i0.ɵɵconditionalCreate(12, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_12_Template, 3, 1, "span",
|
|
763
|
-
i0.ɵɵconditionalCreate(13, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_13_Template, 3, 1, "span",
|
|
764
|
-
i0.ɵɵconditionalCreate(14, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_14_Template, 1, 2, "mj-entity-link-pill",
|
|
761
|
+
i0.ɵɵelementStart(11, "div", 174);
|
|
762
|
+
i0.ɵɵconditionalCreate(12, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_12_Template, 3, 1, "span", 175);
|
|
763
|
+
i0.ɵɵconditionalCreate(13, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_13_Template, 3, 1, "span", 176);
|
|
764
|
+
i0.ɵɵconditionalCreate(14, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_14_Template, 1, 2, "mj-entity-link-pill", 177);
|
|
765
765
|
i0.ɵɵelementEnd();
|
|
766
|
-
i0.ɵɵconditionalCreate(15, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_Template, 3, 0, "div",
|
|
766
|
+
i0.ɵɵconditionalCreate(15, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_15_Template, 3, 0, "div", 178);
|
|
767
767
|
i0.ɵɵelementEnd();
|
|
768
|
-
i0.ɵɵelementStart(16, "div",
|
|
769
|
-
i0.ɵɵelement(17, "i",
|
|
768
|
+
i0.ɵɵelementStart(16, "div", 179);
|
|
769
|
+
i0.ɵɵelement(17, "i", 180);
|
|
770
770
|
i0.ɵɵelementEnd()();
|
|
771
|
-
i0.ɵɵconditionalCreate(18, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template, 35, 18, "div",
|
|
771
|
+
i0.ɵɵconditionalCreate(18, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Conditional_18_Template, 35, 18, "div", 181);
|
|
772
772
|
i0.ɵɵelementEnd();
|
|
773
773
|
} if (rf & 2) {
|
|
774
774
|
const run_r17 = ctx.$implicit;
|
|
@@ -798,7 +798,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2
|
|
|
798
798
|
} }
|
|
799
799
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
800
800
|
i0.ɵɵelementStart(0, "div", 143);
|
|
801
|
-
i0.ɵɵrepeaterCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Template, 19, 22, "div",
|
|
801
|
+
i0.ɵɵrepeaterCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_For_2_Template, 19, 22, "div", 166, i0.ɵɵrepeaterTrackByIdentity);
|
|
802
802
|
i0.ɵɵelementEnd();
|
|
803
803
|
} if (rf & 2) {
|
|
804
804
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -806,39 +806,21 @@ function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_Templ
|
|
|
806
806
|
i0.ɵɵrepeater(ctx_r1.getFilteredTestRuns());
|
|
807
807
|
} }
|
|
808
808
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
809
|
-
i0.ɵɵ
|
|
810
|
-
i0.ɵɵelement(2, "i", 202);
|
|
811
|
-
i0.ɵɵelementEnd();
|
|
812
|
-
i0.ɵɵelementStart(3, "h4");
|
|
813
|
-
i0.ɵɵtext(4, "No Test Runs Found");
|
|
814
|
-
i0.ɵɵelementEnd();
|
|
815
|
-
i0.ɵɵelementStart(5, "p");
|
|
816
|
-
i0.ɵɵtext(6, "No test runs have been recorded for this suite execution.");
|
|
817
|
-
i0.ɵɵelementEnd()();
|
|
809
|
+
i0.ɵɵelement(0, "mj-empty-state", 144);
|
|
818
810
|
} }
|
|
819
811
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
820
812
|
const _r22 = i0.ɵɵgetCurrentView();
|
|
821
|
-
i0.ɵɵelementStart(0, "
|
|
822
|
-
i0.ɵɵ
|
|
813
|
+
i0.ɵɵelementStart(0, "mj-empty-state", 202);
|
|
814
|
+
i0.ɵɵlistener("Action", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_5_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter(null)); });
|
|
823
815
|
i0.ɵɵelementEnd();
|
|
824
|
-
i0.ɵɵelementStart(3, "h4");
|
|
825
|
-
i0.ɵɵtext(4, "No Matching Runs");
|
|
826
|
-
i0.ɵɵelementEnd();
|
|
827
|
-
i0.ɵɵelementStart(5, "p");
|
|
828
|
-
i0.ɵɵtext(6, "No test runs match the current filter.");
|
|
829
|
-
i0.ɵɵelementEnd();
|
|
830
|
-
i0.ɵɵelementStart(7, "button", 151);
|
|
831
|
-
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_5_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r22); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.setRunStatusFilter(null)); });
|
|
832
|
-
i0.ɵɵtext(8, "Clear Filter");
|
|
833
|
-
i0.ɵɵelementEnd()();
|
|
834
816
|
} }
|
|
835
817
|
function MJTestSuiteRunFormComponentExtended_Conditional_130_Template(rf, ctx) { if (rf & 1) {
|
|
836
818
|
i0.ɵɵelementStart(0, "div", 59);
|
|
837
819
|
i0.ɵɵconditionalCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_1_Template, 11, 6, "div", 141);
|
|
838
820
|
i0.ɵɵconditionalCreate(2, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_2_Template, 4, 1, "div", 142);
|
|
839
821
|
i0.ɵɵconditionalCreate(3, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_3_Template, 3, 0, "div", 143);
|
|
840
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_4_Template,
|
|
841
|
-
i0.ɵɵconditionalCreate(5, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_5_Template,
|
|
822
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_4_Template, 1, 0, "mj-empty-state", 144);
|
|
823
|
+
i0.ɵɵconditionalCreate(5, MJTestSuiteRunFormComponentExtended_Conditional_130_Conditional_5_Template, 1, 0, "mj-empty-state", 145);
|
|
842
824
|
i0.ɵɵelementEnd();
|
|
843
825
|
} if (rf & 2) {
|
|
844
826
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -870,71 +852,71 @@ function MJTestSuiteRunFormComponentExtended_Conditional_131_Conditional_16_Temp
|
|
|
870
852
|
i0.ɵɵelementEnd();
|
|
871
853
|
} }
|
|
872
854
|
function MJTestSuiteRunFormComponentExtended_Conditional_131_Template(rf, ctx) { if (rf & 1) {
|
|
873
|
-
i0.ɵɵelementStart(0, "div", 60)(1, "div",
|
|
855
|
+
i0.ɵɵelementStart(0, "div", 60)(1, "div", 203)(2, "h3");
|
|
874
856
|
i0.ɵɵelement(3, "i", 52);
|
|
875
857
|
i0.ɵɵtext(4, " Run Information");
|
|
876
858
|
i0.ɵɵelementEnd();
|
|
877
|
-
i0.ɵɵelementStart(5, "div",
|
|
859
|
+
i0.ɵɵelementStart(5, "div", 204)(6, "div", 205)(7, "div", 206);
|
|
878
860
|
i0.ɵɵtext(8, "Run ID");
|
|
879
861
|
i0.ɵɵelementEnd();
|
|
880
|
-
i0.ɵɵelementStart(9, "div",
|
|
862
|
+
i0.ɵɵelementStart(9, "div", 207);
|
|
881
863
|
i0.ɵɵtext(10);
|
|
882
864
|
i0.ɵɵelementEnd()();
|
|
883
|
-
i0.ɵɵelementStart(11, "div",
|
|
865
|
+
i0.ɵɵelementStart(11, "div", 205)(12, "div", 206);
|
|
884
866
|
i0.ɵɵtext(13, "Test Suite");
|
|
885
867
|
i0.ɵɵelementEnd();
|
|
886
|
-
i0.ɵɵelementStart(14, "div",
|
|
887
|
-
i0.ɵɵconditionalCreate(15, MJTestSuiteRunFormComponentExtended_Conditional_131_Conditional_15_Template, 2, 1, "a",
|
|
868
|
+
i0.ɵɵelementStart(14, "div", 208);
|
|
869
|
+
i0.ɵɵconditionalCreate(15, MJTestSuiteRunFormComponentExtended_Conditional_131_Conditional_15_Template, 2, 1, "a", 209);
|
|
888
870
|
i0.ɵɵconditionalCreate(16, MJTestSuiteRunFormComponentExtended_Conditional_131_Conditional_16_Template, 2, 0, "span");
|
|
889
871
|
i0.ɵɵelementEnd()();
|
|
890
|
-
i0.ɵɵelementStart(17, "div",
|
|
872
|
+
i0.ɵɵelementStart(17, "div", 205)(18, "div", 206);
|
|
891
873
|
i0.ɵɵtext(19, "Status");
|
|
892
874
|
i0.ɵɵelementEnd();
|
|
893
|
-
i0.ɵɵelementStart(20, "div",
|
|
875
|
+
i0.ɵɵelementStart(20, "div", 208)(21, "span", 210);
|
|
894
876
|
i0.ɵɵtext(22);
|
|
895
877
|
i0.ɵɵelementEnd()()();
|
|
896
|
-
i0.ɵɵelementStart(23, "div",
|
|
878
|
+
i0.ɵɵelementStart(23, "div", 205)(24, "div", 206);
|
|
897
879
|
i0.ɵɵtext(25, "Run By");
|
|
898
880
|
i0.ɵɵelementEnd();
|
|
899
|
-
i0.ɵɵelementStart(26, "div",
|
|
881
|
+
i0.ɵɵelementStart(26, "div", 208);
|
|
900
882
|
i0.ɵɵtext(27);
|
|
901
883
|
i0.ɵɵelementEnd()();
|
|
902
|
-
i0.ɵɵelementStart(28, "div",
|
|
884
|
+
i0.ɵɵelementStart(28, "div", 205)(29, "div", 206);
|
|
903
885
|
i0.ɵɵtext(30, "Started At");
|
|
904
886
|
i0.ɵɵelementEnd();
|
|
905
|
-
i0.ɵɵelementStart(31, "div",
|
|
887
|
+
i0.ɵɵelementStart(31, "div", 208);
|
|
906
888
|
i0.ɵɵtext(32);
|
|
907
889
|
i0.ɵɵpipe(33, "date");
|
|
908
890
|
i0.ɵɵelementEnd()();
|
|
909
|
-
i0.ɵɵelementStart(34, "div",
|
|
891
|
+
i0.ɵɵelementStart(34, "div", 205)(35, "div", 206);
|
|
910
892
|
i0.ɵɵtext(36, "Completed At");
|
|
911
893
|
i0.ɵɵelementEnd();
|
|
912
|
-
i0.ɵɵelementStart(37, "div",
|
|
894
|
+
i0.ɵɵelementStart(37, "div", 208);
|
|
913
895
|
i0.ɵɵtext(38);
|
|
914
896
|
i0.ɵɵpipe(39, "date");
|
|
915
897
|
i0.ɵɵelementEnd()();
|
|
916
|
-
i0.ɵɵelementStart(40, "div",
|
|
898
|
+
i0.ɵɵelementStart(40, "div", 205)(41, "div", 206);
|
|
917
899
|
i0.ɵɵtext(42, "Environment");
|
|
918
900
|
i0.ɵɵelementEnd();
|
|
919
|
-
i0.ɵɵelementStart(43, "div",
|
|
901
|
+
i0.ɵɵelementStart(43, "div", 208);
|
|
920
902
|
i0.ɵɵtext(44);
|
|
921
903
|
i0.ɵɵelementEnd()();
|
|
922
|
-
i0.ɵɵelementStart(45, "div",
|
|
904
|
+
i0.ɵɵelementStart(45, "div", 205)(46, "div", 206);
|
|
923
905
|
i0.ɵɵtext(47, "Trigger Type");
|
|
924
906
|
i0.ɵɵelementEnd();
|
|
925
|
-
i0.ɵɵelementStart(48, "div",
|
|
907
|
+
i0.ɵɵelementStart(48, "div", 208);
|
|
926
908
|
i0.ɵɵtext(49);
|
|
927
909
|
i0.ɵɵelementEnd()();
|
|
928
|
-
i0.ɵɵelementStart(50, "div",
|
|
910
|
+
i0.ɵɵelementStart(50, "div", 205)(51, "div", 206);
|
|
929
911
|
i0.ɵɵtext(52, "Git Commit");
|
|
930
912
|
i0.ɵɵelementEnd();
|
|
931
|
-
i0.ɵɵelementStart(53, "div",
|
|
913
|
+
i0.ɵɵelementStart(53, "div", 207);
|
|
932
914
|
i0.ɵɵtext(54);
|
|
933
915
|
i0.ɵɵelementEnd()();
|
|
934
|
-
i0.ɵɵelementStart(55, "div",
|
|
916
|
+
i0.ɵɵelementStart(55, "div", 205)(56, "div", 206);
|
|
935
917
|
i0.ɵɵtext(57, "Agent Version");
|
|
936
918
|
i0.ɵɵelementEnd();
|
|
937
|
-
i0.ɵɵelementStart(58, "div",
|
|
919
|
+
i0.ɵɵelementStart(58, "div", 208);
|
|
938
920
|
i0.ɵɵtext(59);
|
|
939
921
|
i0.ɵɵelementEnd()()()()();
|
|
940
922
|
} if (rf & 2) {
|
|
@@ -965,14 +947,14 @@ function MJTestSuiteRunFormComponentExtended_Conditional_131_Template(rf, ctx) {
|
|
|
965
947
|
i0.ɵɵtextInterpolate(ctx_r1.record.AgentVersion || "N/A");
|
|
966
948
|
} }
|
|
967
949
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
968
|
-
i0.ɵɵelementStart(0, "div",
|
|
950
|
+
i0.ɵɵelementStart(0, "div", 211);
|
|
969
951
|
i0.ɵɵelement(1, "i", 90);
|
|
970
952
|
i0.ɵɵelementStart(2, "span");
|
|
971
953
|
i0.ɵɵtext(3, "Loading test results...");
|
|
972
954
|
i0.ɵɵelementEnd()();
|
|
973
955
|
} }
|
|
974
956
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_2_Template(rf, ctx) { if (rf & 1) {
|
|
975
|
-
i0.ɵɵelementStart(0, "div",
|
|
957
|
+
i0.ɵɵelementStart(0, "div", 212)(1, "h3");
|
|
976
958
|
i0.ɵɵelement(2, "i", 214);
|
|
977
959
|
i0.ɵɵtext(3, " Summary Statistics");
|
|
978
960
|
i0.ɵɵelementEnd();
|
|
@@ -1080,7 +1062,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_3
|
|
|
1080
1062
|
} }
|
|
1081
1063
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_35_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
1082
1064
|
i0.ɵɵelementStart(0, "td", 236)(1, "span", 14);
|
|
1083
|
-
i0.ɵɵelement(2, "i",
|
|
1065
|
+
i0.ɵɵelement(2, "i", 180);
|
|
1084
1066
|
i0.ɵɵtext(3);
|
|
1085
1067
|
i0.ɵɵelementEnd()();
|
|
1086
1068
|
} if (rf & 2) {
|
|
@@ -1126,7 +1108,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_3
|
|
|
1126
1108
|
} }
|
|
1127
1109
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_35_Conditional_10_Conditional_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
1128
1110
|
i0.ɵɵelementStart(0, "span", 255);
|
|
1129
|
-
i0.ɵɵelement(1, "i",
|
|
1111
|
+
i0.ɵɵelement(1, "i", 180);
|
|
1130
1112
|
i0.ɵɵelementEnd();
|
|
1131
1113
|
} if (rf & 2) {
|
|
1132
1114
|
const run_r25 = i0.ɵɵnextContext(3).$implicit;
|
|
@@ -1221,11 +1203,11 @@ function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_3
|
|
|
1221
1203
|
i0.ɵɵelementEnd()();
|
|
1222
1204
|
} if (rf & 2) {
|
|
1223
1205
|
const run_r25 = ctx.$implicit;
|
|
1224
|
-
const ɵ$
|
|
1206
|
+
const ɵ$index_1001_r27 = ctx.$index;
|
|
1225
1207
|
const ctx_r1 = i0.ɵɵnextContext(3);
|
|
1226
1208
|
i0.ɵɵclassProp("row-passed", run_r25.Status === "Passed")("row-failed", run_r25.Status === "Failed")("row-error", run_r25.Status === "Error")("row-skipped", run_r25.Status === "Skipped");
|
|
1227
1209
|
i0.ɵɵadvance(2);
|
|
1228
|
-
i0.ɵɵtextInterpolate(ɵ$
|
|
1210
|
+
i0.ɵɵtextInterpolate(ɵ$index_1001_r27 + 1);
|
|
1229
1211
|
i0.ɵɵadvance(4);
|
|
1230
1212
|
i0.ɵɵtextInterpolate(run_r25.Test || "Unknown Test");
|
|
1231
1213
|
i0.ɵɵadvance();
|
|
@@ -1246,7 +1228,7 @@ function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_For_3
|
|
|
1246
1228
|
i0.ɵɵconditional(!run_r25.CostUSD ? 16 : -1);
|
|
1247
1229
|
} }
|
|
1248
1230
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_Template(rf, ctx) { if (rf & 1) {
|
|
1249
|
-
i0.ɵɵelementStart(0, "div",
|
|
1231
|
+
i0.ɵɵelementStart(0, "div", 212)(1, "div", 225)(2, "h3");
|
|
1250
1232
|
i0.ɵɵelement(3, "i", 226);
|
|
1251
1233
|
i0.ɵɵtext(4, " Test Results");
|
|
1252
1234
|
i0.ɵɵelementEnd();
|
|
@@ -1296,22 +1278,14 @@ function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_Templ
|
|
|
1296
1278
|
i0.ɵɵrepeater(ctx_r1.testRuns);
|
|
1297
1279
|
} }
|
|
1298
1280
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_4_Template(rf, ctx) { if (rf & 1) {
|
|
1299
|
-
i0.ɵɵ
|
|
1300
|
-
i0.ɵɵelement(2, "i", 54);
|
|
1301
|
-
i0.ɵɵelementEnd();
|
|
1302
|
-
i0.ɵɵelementStart(3, "h4");
|
|
1303
|
-
i0.ɵɵtext(4, "No Test Results Yet");
|
|
1304
|
-
i0.ɵɵelementEnd();
|
|
1305
|
-
i0.ɵɵelementStart(5, "p");
|
|
1306
|
-
i0.ɵɵtext(6, "Test runs will appear here once the suite execution completes.");
|
|
1307
|
-
i0.ɵɵelementEnd()();
|
|
1281
|
+
i0.ɵɵelement(0, "mj-empty-state", 213);
|
|
1308
1282
|
} }
|
|
1309
1283
|
function MJTestSuiteRunFormComponentExtended_Conditional_132_Template(rf, ctx) { if (rf & 1) {
|
|
1310
1284
|
i0.ɵɵelementStart(0, "div", 61);
|
|
1311
|
-
i0.ɵɵconditionalCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_1_Template, 4, 0, "div",
|
|
1312
|
-
i0.ɵɵconditionalCreate(2, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_2_Template, 49, 7, "div",
|
|
1313
|
-
i0.ɵɵconditionalCreate(3, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_Template, 36, 3, "div",
|
|
1314
|
-
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_4_Template,
|
|
1285
|
+
i0.ɵɵconditionalCreate(1, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_1_Template, 4, 0, "div", 211);
|
|
1286
|
+
i0.ɵɵconditionalCreate(2, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_2_Template, 49, 7, "div", 212);
|
|
1287
|
+
i0.ɵɵconditionalCreate(3, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_3_Template, 36, 3, "div", 212);
|
|
1288
|
+
i0.ɵɵconditionalCreate(4, MJTestSuiteRunFormComponentExtended_Conditional_132_Conditional_4_Template, 1, 0, "mj-empty-state", 213);
|
|
1315
1289
|
i0.ɵɵelementEnd();
|
|
1316
1290
|
} if (rf & 2) {
|
|
1317
1291
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -2075,7 +2049,7 @@ let MJTestSuiteRunFormComponentExtended = class MJTestSuiteRunFormComponentExten
|
|
|
2075
2049
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJTestSuiteRunFormComponentExtended_BaseFactory; return function MJTestSuiteRunFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJTestSuiteRunFormComponentExtended_BaseFactory || (ɵMJTestSuiteRunFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJTestSuiteRunFormComponentExtended)))(__ngFactoryType__ || MJTestSuiteRunFormComponentExtended); }; })(); }
|
|
2076
2050
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJTestSuiteRunFormComponentExtended, selectors: [["mj-test-suite-run-form"]], hostBindings: function MJTestSuiteRunFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
|
|
2077
2051
|
i0.ɵɵlistener("keydown", function MJTestSuiteRunFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, i0.ɵɵresolveDocument);
|
|
2078
|
-
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 137, vars: 48, consts: [[1, "test-suite-run-form"], [1, "suite-run-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, "header-content"], [1, "header-left"], [1, "suite-run-icon"], [1, "fas", 3, "ngClass"], [1, "suite-run-info"], [1, "suite-run-meta"], [1, "status-badge", 3, "ngClass"], [1, "meta-tag", "environment"], [1, "meta-tag", "trigger"], [1, "header-actions"], ["mjButton", "", "variant", "primary"], ["mjButton", "", 3, "click", "disabled"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-icon"], [1, "fas", "fa-clock"], [1, "metric-content"], [1, "metric-value"], [1, "metric-label"], [1, "fas", "fa-percentage"], [1, "fas", "fa-dollar-sign"], [1, "fas", "fa-calendar"], [1, "results-summary"], [1, "result-item", "passed"], [1, "result-icon"], [1, "fas", "fa-check-circle"], [1, "result-content"], [1, "result-count"], [1, "result-label"], [1, "result-item", "failed"], [1, "fas", "fa-times-circle"], [1, "result-item", "error"], [1, "fas", "fa-exclamation-circle"], [1, "result-item", "skipped"], [1, "fas", "fa-forward"], [1, "result-item", "total"], [1, "fas", "fa-list"], [1, "tags-bar"], [1, "tags-editor-panel"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "tab-badge"], [1, "fas", "fa-info-circle"], ["role", "tab", "title", "Press 4", 1, "tab", 3, "click"], [1, "fas", "fa-chart-bar"], ["role", "tab", "title", "Press 5", 1, "tab", 3, "click"], [1, "fas", "fa-microchip"], [1, "tab-content"], [1, "overview-tab"], [1, "runs-tab"], [1, "details-tab"], [1, "analytics-tab"], [1, "execution-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-server"], [1, "fas", "fa-bolt"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], [1, "tags-bar-content"], [1, "tags-bar-label"], [1, "fas", "fa-tags"], [1, "tags-bar-chips"], [1, "tags-bar-empty"], ["title", "Edit tags", 1, "tags-bar-edit", 3, "click"], [1, "fas", "fa-plus"], [1, "tag-inline"], [1, "tags-editor-header"], [1, "tags-editor-title"], [1, "tags-editor-body"], [1, "tags-editor-chips"], [1, "tag-editable"], [1, "tags-empty-hint"], [1, "tags-editor-input"], ["type", "text", "placeholder", "Type a tag and press Enter...", 1, "tag-text-input", 3, "ngModelChange", "keyup.enter", "ngModel"], ["mjButton", "", "variant", "flat", 3, "click", "disabled"], [1, "tags-editor-footer"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["mjButton", "", "variant", "flat", 3, "click"], ["title", "Remove tag", 1, "tag-remove-btn", 3, "click"], [1, "fas", "fa-times"], [1, "result-hero"], [1, "result-hero-icon"], [1, "result-hero-text"], [1, "result-hero-stats"], [1, "stat-item"], [1, "stat-value"], [1, "stat-label"], [1, "stat-divider"], [1, "evaluation-summary"], [1, "needs-review-section"], [1, "progress-section"], [1, "eval-summary-grid"], [1, "eval-summary-card"], [1, "eval-card-header"], [1, "fa-solid", "fa-user"], [1, "eval-card-body"], [1, "eval-stat-row"], [1, "eval-stat-label"], [1, "eval-stat-value"], [1, "eval-card-footer"], [1, "eval-stat-value", "correct"], [1, "eval-stat-value", "incorrect"], [1, "pending-badge"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-circle-check"], [1, "eval-stat-value", "error"], [1, "eval-stat-value", "timeout"], [1, "needs-review-header"], [1, "fa-solid", "fa-user-clock"], [1, "review-count"], [1, "needs-review-list"], [1, "review-item", 3, "high-priority", "medium-priority"], [1, "review-more"], [1, "review-item", 3, "click"], [1, "review-item-icon"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-circle-dot"], [1, "review-item-content"], [1, "review-item-name"], [1, "review-item-reason"], [1, "review-item-action"], [1, "fa-solid", "fa-chevron-right"], [1, "progress-info"], [1, "fas", "fa-circle-notch", "fa-spin"], [1, "auto-refresh-notice"], [1, "fas", "fa-sync"], [1, "runs-toolbar"], [1, "loading-state"], [1, "test-runs-list"], [
|
|
2052
|
+
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 137, vars: 48, consts: [[1, "test-suite-run-form"], [1, "suite-run-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, "header-content"], [1, "header-left"], [1, "suite-run-icon"], [1, "fas", 3, "ngClass"], [1, "suite-run-info"], [1, "suite-run-meta"], [1, "status-badge", 3, "ngClass"], [1, "meta-tag", "environment"], [1, "meta-tag", "trigger"], [1, "header-actions"], ["mjButton", "", "variant", "primary"], ["mjButton", "", 3, "click", "disabled"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-icon"], [1, "fas", "fa-clock"], [1, "metric-content"], [1, "metric-value"], [1, "metric-label"], [1, "fas", "fa-percentage"], [1, "fas", "fa-dollar-sign"], [1, "fas", "fa-calendar"], [1, "results-summary"], [1, "result-item", "passed"], [1, "result-icon"], [1, "fas", "fa-check-circle"], [1, "result-content"], [1, "result-count"], [1, "result-label"], [1, "result-item", "failed"], [1, "fas", "fa-times-circle"], [1, "result-item", "error"], [1, "fas", "fa-exclamation-circle"], [1, "result-item", "skipped"], [1, "fas", "fa-forward"], [1, "result-item", "total"], [1, "fas", "fa-list"], [1, "tags-bar"], [1, "tags-editor-panel"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", 1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "tab-badge"], [1, "fas", "fa-info-circle"], ["role", "tab", "title", "Press 4", 1, "tab", 3, "click"], [1, "fas", "fa-chart-bar"], ["role", "tab", "title", "Press 5", 1, "tab", 3, "click"], [1, "fas", "fa-microchip"], [1, "tab-content"], [1, "overview-tab"], [1, "runs-tab"], [1, "details-tab"], [1, "analytics-tab"], [1, "execution-tab"], [1, "shortcuts-toggle", 3, "click", "title"], [1, "fas", "fa-keyboard"], [1, "keyboard-shortcuts"], [1, "fas", "fa-layer-group"], [1, "fas", "fa-server"], [1, "fas", "fa-bolt"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fas", "fa-play"], [1, "tags-bar-content"], [1, "tags-bar-label"], [1, "fas", "fa-tags"], [1, "tags-bar-chips"], [1, "tags-bar-empty"], ["title", "Edit tags", 1, "tags-bar-edit", 3, "click"], [1, "fas", "fa-plus"], [1, "tag-inline"], [1, "tags-editor-header"], [1, "tags-editor-title"], [1, "tags-editor-body"], [1, "tags-editor-chips"], [1, "tag-editable"], [1, "tags-empty-hint"], [1, "tags-editor-input"], ["type", "text", "placeholder", "Type a tag and press Enter...", 1, "tag-text-input", 3, "ngModelChange", "keyup.enter", "ngModel"], ["mjButton", "", "variant", "flat", 3, "click", "disabled"], [1, "tags-editor-footer"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], [1, "fas", "fa-spinner", "fa-spin"], ["mjButton", "", "variant", "flat", 3, "click"], ["title", "Remove tag", 1, "tag-remove-btn", 3, "click"], [1, "fas", "fa-times"], [1, "result-hero"], [1, "result-hero-icon"], [1, "result-hero-text"], [1, "result-hero-stats"], [1, "stat-item"], [1, "stat-value"], [1, "stat-label"], [1, "stat-divider"], [1, "evaluation-summary"], [1, "needs-review-section"], [1, "progress-section"], [1, "eval-summary-grid"], [1, "eval-summary-card"], [1, "eval-card-header"], [1, "fa-solid", "fa-user"], [1, "eval-card-body"], [1, "eval-stat-row"], [1, "eval-stat-label"], [1, "eval-stat-value"], [1, "eval-card-footer"], [1, "eval-stat-value", "correct"], [1, "eval-stat-value", "incorrect"], [1, "pending-badge"], [1, "fa-solid", "fa-clock"], [1, "fa-solid", "fa-robot"], [1, "fa-solid", "fa-circle-check"], [1, "eval-stat-value", "error"], [1, "eval-stat-value", "timeout"], [1, "needs-review-header"], [1, "fa-solid", "fa-user-clock"], [1, "review-count"], [1, "needs-review-list"], [1, "review-item", 3, "high-priority", "medium-priority"], [1, "review-more"], [1, "review-item", 3, "click"], [1, "review-item-icon"], [1, "fa-solid", "fa-exclamation-triangle"], [1, "fa-solid", "fa-circle-dot"], [1, "review-item-content"], [1, "review-item-name"], [1, "review-item-reason"], [1, "review-item-action"], [1, "fa-solid", "fa-chevron-right"], [1, "progress-info"], [1, "fas", "fa-circle-notch", "fa-spin"], [1, "auto-refresh-notice"], [1, "fas", "fa-sync"], [1, "runs-toolbar"], [1, "loading-state"], [1, "test-runs-list"], ["Icon", "fa-solid fa-inbox", "Title", "No Test Runs Found", "Message", "No test runs have been recorded for this suite execution."], ["Variant", "no-results", "Icon", "fa-solid fa-filter", "Title", "No Matching Runs", "Message", "No test runs match the current filter.", "ActionText", "Clear Filter", "ActionVariant", "outline"], [1, "run-filters"], [1, "filter-btn", 3, "click"], [1, "filter-btn", "passed", 3, "active"], [1, "filter-btn", "failed", 3, "active"], [1, "filter-btn", "error", 3, "active"], [1, "runs-actions"], ["mjButton", "", 3, "click"], [1, "fas", "fa-download"], [1, "filter-btn", "passed", 3, "click"], [1, "fas", "fa-check"], [1, "filter-btn", "failed", 3, "click"], [1, "filter-btn", "error", 3, "click"], [1, "fas", "fa-exclamation"], [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-run-card"], [1, "test-run-item", 3, "click"], [1, "run-sequence"], [1, "run-icon"], [1, "run-content"], [1, "run-header-row"], [1, "run-name"], [3, "executionStatus", "originalStatus", "autoScore", "humanRating", "humanIsCorrect", "hasHumanFeedback", "preferences", "mode"], [1, "run-meta"], [1, "run-duration"], [1, "run-cost"], [3, "entityName", "recordId"], [1, "run-tags"], [1, "run-expand"], [1, "fas"], [1, "inline-feedback"], [1, "tag-chip"], [1, "feedback-divider"], [1, "feedback-section"], [1, "feedback-label"], [1, "inline-rating"], [1, "rating-numbers"], ["type", "button", 1, "rating-btn", 3, "selected", "hover", "low", "mid", "high"], [1, "rating-info"], [1, "correctness-row"], [1, "correctness-label"], [1, "correctness-options"], [1, "radio-opt", 3, "click"], ["type", "radio", 3, "ngModelChange", "name", "value", "ngModel"], [1, "comments-row", 3, "click"], ["placeholder", "Add comments or corrections...", "rows", "3", 1, "feedback-textarea", 3, "ngModelChange", "ngModel"], [1, "feedback-actions", 3, "click"], [1, "fas", "fa-external-link-alt"], ["type", "button", 1, "rating-btn", 3, "click", "mouseenter", "mouseleave"], [1, "rating-value"], [1, "rating-label-text"], ["Variant", "no-results", "Icon", "fa-solid fa-filter", "Title", "No Matching Runs", "Message", "No test runs match the current filter.", "ActionText", "Clear Filter", "ActionVariant", "outline", 3, "Action"], [1, "details-card"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "detail-value", "monospace"], [1, "detail-value"], ["href", "javascript:void(0)"], [1, "status-inline", 3, "ngClass"], [1, "analytics-loading"], [1, "analytics-section"], ["Icon", "fa-solid fa-chart-bar", "Title", "No Test Results Yet", "Message", "Test runs will appear here once the suite execution completes."], [1, "fas", "fa-chart-pie"], [1, "stats-grid"], [1, "stat-card"], [1, "stat-icon", "passed"], [1, "stat-content"], [1, "stat-percent"], [1, "stat-icon", "failed"], [1, "stat-icon", "score"], [1, "fas", "fa-star"], [1, "stat-icon", "duration"], [1, "stat-icon", "cost"], [1, "analytics-header"], [1, "fas", "fa-table"], [1, "analytics-legend"], [1, "legend-item", "passed"], [1, "legend-item", "failed"], [1, "legend-item", "error"], [1, "legend-item", "skipped"], [1, "results-table-wrapper"], [1, "results-table"], [1, "seq-col"], [1, "name-col"], [1, "status-col"], [1, "score-col"], [1, "feedback-col"], [1, "duration-col"], [1, "cost-col"], [1, "result-row", 3, "row-passed", "row-failed", "row-error", "row-skipped"], [1, "result-row", 3, "click"], [1, "test-name-wrapper"], [1, "test-name"], [1, "test-tags"], [1, "na-value"], [1, "tag-mini"], [1, "score-display"], [1, "score-bar-mini"], [1, "score-fill"], [1, "score-text"], [1, "feedback-display"], [1, "na-value", "needs-review"], [1, "feedback-rating"], [1, "feedback-correctness"], [1, "fas", "fa-user-clock"], [3, "machineName", "machineId", "runByUserName", "runByUserEmail", "runContextDetailsJson"], [1, "shortcuts-header"], ["title", "Hide shortcuts", 1, "shortcuts-close", 3, "click"], [1, "shortcut-list"], [1, "shortcut-item"], [1, "shortcut-keys"]], template: function MJTestSuiteRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
2079
2053
|
i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "nav", 2)(3, "ol")(4, "li")(5, "a", 3);
|
|
2080
2054
|
i0.ɵɵlistener("click", function MJTestSuiteRunFormComponentExtended_Template_a_click_5_listener() { return ctx.navigateToTestingDashboard(); });
|
|
2081
2055
|
i0.ɵɵelement(6, "i", 4);
|
|
@@ -2313,7 +2287,7 @@ let MJTestSuiteRunFormComponentExtended = class MJTestSuiteRunFormComponentExten
|
|
|
2313
2287
|
i0.ɵɵproperty("title", ctx.showShortcuts ? "Hide keyboard shortcuts" : "Show keyboard shortcuts");
|
|
2314
2288
|
i0.ɵɵadvance(2);
|
|
2315
2289
|
i0.ɵɵconditional(ctx.showShortcuts ? 136 : -1);
|
|
2316
|
-
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.RadioControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJButtonDirective, i4.EvaluationBadgeComponent, i4.EvaluationModeToggleComponent, i4.ExecutionContextComponent, i5.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --suite-run-primary: var(--mj-brand-primary);\n --suite-run-primary-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-success: var(--mj-status-success);\n --suite-run-success-light: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n --suite-run-danger: var(--mj-status-error);\n --suite-run-danger-light: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n --suite-run-warning: var(--mj-status-warning);\n --suite-run-warning-light: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --suite-run-info: var(--mj-brand-primary);\n --suite-run-info-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-neutral: var(--mj-text-muted);\n --suite-run-neutral-light: var(--mj-bg-surface-card);\n --suite-run-bg: var(--mj-bg-surface-card);\n --suite-run-card: var(--mj-bg-surface);\n --suite-run-border: var(--mj-border-default);\n --suite-run-text: var(--mj-text-primary);\n --suite-run-text-secondary: var(--mj-text-muted);\n --suite-run-radius: 12px;\n --suite-run-shadow: var(--mj-shadow-sm);\n --suite-run-shadow-lg: var(--mj-shadow-lg);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n.test-suite-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n\n\n\n\n.suite-run-header[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\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(--suite-run-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(--suite-run-text-secondary);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--suite-run-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.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\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 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n\n\n\n\n.results-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.result-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.passed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-item.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.failed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-item.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.error[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.skipped[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.total[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--suite-run-border);\n color: var(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon[_ngcontent-%COMP%] {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider[_ngcontent-%COMP%] {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n\n\n.progress-section[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n}\n\n.auto-refresh-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n\n\n.runs-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] {\n width: 70%;\n}\n\n.skeleton-line.narrow[_ngcontent-%COMP%] {\n width: 40%;\n}\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n.test-runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateX(4px);\n}\n\n.test-run-item[_ngcontent-%COMP%]:active {\n transform: translateX(2px);\n}\n\n.run-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.run-score[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n transform: translateX(4px);\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 20px;\n text-align: center;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 2px dashed var(--suite-run-border);\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(--suite-run-neutral-light);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--mj-border-strong);\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(--suite-run-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--suite-run-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 20px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.status-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\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(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-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 gap: 16px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\nkbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 var(--mj-text-disabled);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider[_ngcontent-%COMP%] {\n display: none;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .suite-run-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 8px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .results-summary[_ngcontent-%COMP%] {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 16px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 32px 20px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 56px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 10px;\n font-size: 11px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 16px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n\n .details-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n gap: 16px;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .suite-run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .meta-tag[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .result-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 16px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .progress-section[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .progress-info[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n font-size: 10px;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 32px 12px;\n }\n\n .empty-state[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .details-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .test-run-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n\n .test-run-item[_ngcontent-%COMP%]:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n\n .tab[_ngcontent-%COMP%]:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .suite-run-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n box-shadow: none;\n border-bottom: 2px solid var(--mj-text-primary);\n }\n\n .tabs-container[_ngcontent-%COMP%], \n .header-actions[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 20px 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .test-run-item[_ngcontent-%COMP%], \n .details-card[_ngcontent-%COMP%] {\n box-shadow: none;\n border: 1px solid var(--mj-border-strong);\n }\n}\n\n\n\n\n\n@media (prefers-color-scheme: dark) {\n \n\n}\n\n\n\n\n\n.tags-bar[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.tags-bar-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n\n\n.tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--suite-run-primary-light);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n\n\n.runs-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.passed[_ngcontent-%COMP%]:hover, \n.filter-btn.passed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.failed[_ngcontent-%COMP%]:hover, \n.filter-btn.failed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.error[_ngcontent-%COMP%]:hover, \n.filter-btn.error.active[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.runs-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n\n\n.test-run-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\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) 10%, 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.run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover .run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.run-cost[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n\n\n\n\n.inline-feedback[_ngcontent-%COMP%] {\n padding: 0 16px 16px;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn[_ngcontent-%COMP%]:hover, \n.rating-btn.hover[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.low[_ngcontent-%COMP%]:hover, \n.rating-btn.low.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid[_ngcontent-%COMP%]:hover, \n.rating-btn.mid.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high[_ngcontent-%COMP%]:hover, \n.rating-btn.high.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.selected.low[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.mid[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.high[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.rating-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.feedback-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.feedback-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .tags-bar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .tags-bar-content[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .tag-inline[_ngcontent-%COMP%] {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .tags-editor-body[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .tags-editor-footer[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .runs-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .runs-actions[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-numbers[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .feedback-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%], \n.runs-tab[_ngcontent-%COMP%], \n.details-tab[_ngcontent-%COMP%], \n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.analytics-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: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n\n\n.performance-matrix[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.matrix-row[_ngcontent-%COMP%]:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell[_ngcontent-%COMP%] {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n gap: 12px;\n}\n\n.test-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.score-bar[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n}\n\n.score-fill.medium[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n}\n\n.score-fill.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n}\n\n.score-text[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n@media (max-width: 768px) {\n .analytics-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row[_ngcontent-%COMP%] {\n display: none;\n }\n\n .matrix-cell[_ngcontent-%COMP%] {\n padding: 4px 0;\n }\n\n .test-name-cell[_ngcontent-%COMP%]::before, \n .status-cell[_ngcontent-%COMP%]::before, \n .score-cell[_ngcontent-%COMP%]::before, \n .duration-cell[_ngcontent-%COMP%]::before, \n .cost-cell[_ngcontent-%COMP%]::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell[_ngcontent-%COMP%]::before { content: 'Status:'; }\n .score-cell[_ngcontent-%COMP%]::before { content: 'Score:'; }\n .duration-cell[_ngcontent-%COMP%]::before { content: 'Duration:'; }\n .cost-cell[_ngcontent-%COMP%]::before { content: 'Cost:'; }\n\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .stat-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n}\n\n\n\n.tab[_ngcontent-%COMP%]:focus-visible, \n.test-run-item[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.analytics-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.results-table-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n vertical-align: middle;\n}\n\n.results-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n\n\n.seq-col[_ngcontent-%COMP%] {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col[_ngcontent-%COMP%] {\n \n\n width: auto;\n max-width: 50%;\n}\n\n.status-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n}\n\n.score-col[_ngcontent-%COMP%] {\n width: 1%; \n\n min-width: 120px; \n\n white-space: nowrap;\n}\n\n.duration-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n\n\n.result-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n\n\n.test-name-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper[_ngcontent-%COMP%] .test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n\n\n.score-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.medium[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n}\n\n.score-display[_ngcontent-%COMP%] .score-text[_ngcontent-%COMP%] {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n\n\n.results-table[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-error[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-skipped[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n\n\n@media (max-width: 768px) {\n .results-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n\n .results-table[_ngcontent-%COMP%] {\n min-width: 600px;\n }\n\n .results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .name-col[_ngcontent-%COMP%] {\n min-width: 150px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%], \n .status-inline[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n border-width: 2px;\n }\n\n .tab.active[_ngcontent-%COMP%] {\n border-bottom-width: 4px;\n }\n}\n\n\n\n\n\n.evaluation-summary[_ngcontent-%COMP%] {\n margin-top: 20px;\n}\n\n.eval-summary-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer[_ngcontent-%COMP%] {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n}\n\n.pending-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n\n\n.needs-review-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-warning);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.review-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-warning);\n background: color-mix(in srgb, var(--mj-bg-surface) 60%, transparent);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list[_ngcontent-%COMP%] {\n padding: 8px;\n}\n\n.review-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item[_ngcontent-%COMP%]:not(.high-priority):not(.medium-priority) .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item[_ngcontent-%COMP%]:hover .review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.review-more[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n@media (max-width: 768px) {\n .eval-summary-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header[_ngcontent-%COMP%] {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body[_ngcontent-%COMP%] {\n padding: 12px 14px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .review-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .review-item-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n.feedback-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}"], changeDetection: 0 }); }
|
|
2290
|
+
} }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.RadioControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.MJEmptyStateComponent, i3.MJButtonDirective, i4.EvaluationBadgeComponent, i4.EvaluationModeToggleComponent, i4.ExecutionContextComponent, i5.EntityLinkPillComponent, i1.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --suite-run-primary: var(--mj-brand-primary);\n --suite-run-primary-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-success: var(--mj-status-success);\n --suite-run-success-light: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n --suite-run-danger: var(--mj-status-error);\n --suite-run-danger-light: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n --suite-run-warning: var(--mj-status-warning);\n --suite-run-warning-light: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --suite-run-info: var(--mj-brand-primary);\n --suite-run-info-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-neutral: var(--mj-text-muted);\n --suite-run-neutral-light: var(--mj-bg-surface-card);\n --suite-run-bg: var(--mj-bg-surface-card);\n --suite-run-card: var(--mj-bg-surface);\n --suite-run-border: var(--mj-border-default);\n --suite-run-text: var(--mj-text-primary);\n --suite-run-text-secondary: var(--mj-text-muted);\n --suite-run-radius: 12px;\n --suite-run-shadow: var(--mj-shadow-sm);\n --suite-run-shadow-lg: var(--mj-shadow-lg);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n.test-suite-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n\n\n\n\n.suite-run-header[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\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(--suite-run-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(--suite-run-text-secondary);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--suite-run-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.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\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 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n\n\n\n\n.results-summary[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n.result-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n}\n\n.result-count[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.passed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-item.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.failed[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-item.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.error[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.skipped[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-item.total[_ngcontent-%COMP%] .result-count[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--suite-run-border);\n color: var(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon[_ngcontent-%COMP%] {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider[_ngcontent-%COMP%] {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n\n\n.progress-section[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n}\n\n.auto-refresh-notice[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n\n\n.runs-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] {\n width: 70%;\n}\n\n.skeleton-line.narrow[_ngcontent-%COMP%] {\n width: 40%;\n}\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n.test-runs-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateX(4px);\n}\n\n.test-run-item[_ngcontent-%COMP%]:active {\n transform: translateX(2px);\n}\n\n.run-sequence[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status[_ngcontent-%COMP%] {\n font-weight: 700;\n}\n\n.run-score[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score[_ngcontent-%COMP%] i[_ngcontent-%COMP%], \n.run-duration[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: var(--mj-border-strong);\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n transform: translateX(4px);\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 20px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.status-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\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(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle[_ngcontent-%COMP%]:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.shortcuts-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close[_ngcontent-%COMP%] {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close[_ngcontent-%COMP%]:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-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 gap: 16px;\n}\n\n.shortcut-item[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\nkbd[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 var(--mj-text-disabled);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px 20px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider[_ngcontent-%COMP%] {\n display: none;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .suite-run-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 8px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .results-summary[_ngcontent-%COMP%] {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 16px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 32px 20px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 56px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 10px;\n font-size: 11px;\n }\n\n .details-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n gap: 16px;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%], .shortcuts-toggle[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .suite-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .suite-run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .meta-tag[_ngcontent-%COMP%] {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .result-item[_ngcontent-%COMP%] {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .result-count[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .result-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 16px;\n }\n\n .result-hero-icon[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .stat-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .progress-section[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .progress-info[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name[_ngcontent-%COMP%] {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n font-size: 10px;\n }\n\n .details-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .details-card[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label[_ngcontent-%COMP%] {\n font-size: 10px;\n }\n\n .detail-value[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .test-run-item[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n\n .test-run-item[_ngcontent-%COMP%]:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n\n .tab[_ngcontent-%COMP%]:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item[_ngcontent-%COMP%]:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .suite-run-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n box-shadow: none;\n border-bottom: 2px solid var(--mj-text-primary);\n }\n\n .tabs-container[_ngcontent-%COMP%], \n .header-actions[_ngcontent-%COMP%], \n .keyboard-shortcuts[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 20px 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .test-run-item[_ngcontent-%COMP%], \n .details-card[_ngcontent-%COMP%] {\n box-shadow: none;\n border: 1px solid var(--mj-border-strong);\n }\n}\n\n\n\n\n\n@media (prefers-color-scheme: dark) {\n \n\n}\n\n\n\n\n\n.tags-bar[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.tags-bar-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n\n\n.tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--suite-run-primary-light);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n\n\n.runs-toolbar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn[_ngcontent-%COMP%]:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active[_ngcontent-%COMP%] {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.passed[_ngcontent-%COMP%]:hover, \n.filter-btn.passed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.failed[_ngcontent-%COMP%]:hover, \n.filter-btn.failed.active[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.error[_ngcontent-%COMP%]:hover, \n.filter-btn.error.active[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.runs-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n\n\n\n\n.test-run-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.run-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini[_ngcontent-%COMP%] {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\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) 10%, 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.run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item[_ngcontent-%COMP%]:hover .run-expand[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.run-cost[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0.7;\n}\n\n\n\n\n\n.inline-feedback[_ngcontent-%COMP%] {\n padding: 0 16px 16px;\n animation: _ngcontent-%COMP%_slideDown 0.2s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn[_ngcontent-%COMP%]:hover, \n.rating-btn.hover[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.low[_ngcontent-%COMP%]:hover, \n.rating-btn.low.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid[_ngcontent-%COMP%]:hover, \n.rating-btn.mid.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high[_ngcontent-%COMP%]:hover, \n.rating-btn.high.hover[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected[_ngcontent-%COMP%] {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.selected.low[_ngcontent-%COMP%] {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.mid[_ngcontent-%COMP%] {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.high[_ngcontent-%COMP%] {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.rating-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.feedback-textarea[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.feedback-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .tags-bar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .tags-bar-content[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .tag-inline[_ngcontent-%COMP%] {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .tags-editor-body[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .tags-editor-footer[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .runs-toolbar[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .runs-actions[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-numbers[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .rating-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .feedback-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n }\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running[_ngcontent-%COMP%] .result-hero-icon[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%], \n.runs-tab[_ngcontent-%COMP%], \n.details-tab[_ngcontent-%COMP%], \n.analytics-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease;\n}\n\n\n\n\n\n.analytics-tab[_ngcontent-%COMP%] {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.analytics-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: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n\n\n.performance-matrix[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.matrix-row[_ngcontent-%COMP%]:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell[_ngcontent-%COMP%] {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell[_ngcontent-%COMP%] {\n gap: 12px;\n}\n\n.test-sequence[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped[_ngcontent-%COMP%] {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending[_ngcontent-%COMP%] {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.score-bar[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n}\n\n.score-fill.medium[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n}\n\n.score-fill.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n}\n\n.score-text[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n\n\n.stats-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n\n\n@media (max-width: 768px) {\n .analytics-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row[_ngcontent-%COMP%] {\n display: none;\n }\n\n .matrix-cell[_ngcontent-%COMP%] {\n padding: 4px 0;\n }\n\n .test-name-cell[_ngcontent-%COMP%]::before, \n .status-cell[_ngcontent-%COMP%]::before, \n .score-cell[_ngcontent-%COMP%]::before, \n .duration-cell[_ngcontent-%COMP%]::before, \n .cost-cell[_ngcontent-%COMP%]::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell[_ngcontent-%COMP%]::before { content: 'Status:'; }\n .score-cell[_ngcontent-%COMP%]::before { content: 'Score:'; }\n .duration-cell[_ngcontent-%COMP%]::before { content: 'Duration:'; }\n .cost-cell[_ngcontent-%COMP%]::before { content: 'Cost:'; }\n\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .stat-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n}\n\n\n\n.tab[_ngcontent-%COMP%]:focus-visible, \n.test-run-item[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n.analytics-loading[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n\n\n\n\n.results-table-wrapper[_ngcontent-%COMP%] {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n vertical-align: middle;\n}\n\n.results-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child td[_ngcontent-%COMP%] {\n border-bottom: none;\n}\n\n\n\n.seq-col[_ngcontent-%COMP%] {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col[_ngcontent-%COMP%] {\n \n\n width: auto;\n max-width: 50%;\n}\n\n.status-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n}\n\n.score-col[_ngcontent-%COMP%] {\n width: 1%; \n\n min-width: 120px; \n\n white-space: nowrap;\n}\n\n.duration-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: right;\n}\n\n\n\n.result-row[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped[_ngcontent-%COMP%] {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n\n\n.test-name-wrapper[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper[_ngcontent-%COMP%] .test-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n\n\n.score-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.medium[_ngcontent-%COMP%] {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini[_ngcontent-%COMP%] .score-fill.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger);\n}\n\n.score-display[_ngcontent-%COMP%] .score-text[_ngcontent-%COMP%] {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n\n\n.results-table[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-passed[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-failed[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-error[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-skipped[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-pending[_ngcontent-%COMP%] {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table[_ngcontent-%COMP%] .status-badge.status-running[_ngcontent-%COMP%] {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n\n\n@media (max-width: 768px) {\n .results-table-wrapper[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n\n .results-table[_ngcontent-%COMP%] {\n min-width: 600px;\n }\n\n .results-table[_ngcontent-%COMP%] th[_ngcontent-%COMP%], \n .results-table[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .name-col[_ngcontent-%COMP%] {\n min-width: 150px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%], \n .status-inline[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .test-run-item[_ngcontent-%COMP%] {\n border-width: 2px;\n }\n\n .tab.active[_ngcontent-%COMP%] {\n border-bottom-width: 4px;\n }\n}\n\n\n\n\n\n.evaluation-summary[_ngcontent-%COMP%] {\n margin-top: 20px;\n}\n\n.eval-summary-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer[_ngcontent-%COMP%] {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n}\n\n.pending-badge[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n\n\n\n\n.needs-review-section[_ngcontent-%COMP%] {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-warning);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.review-count[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-warning);\n background: color-mix(in srgb, var(--mj-bg-surface) 60%, transparent);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list[_ngcontent-%COMP%] {\n padding: 8px;\n}\n\n.review-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item[_ngcontent-%COMP%]:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority[_ngcontent-%COMP%] .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item[_ngcontent-%COMP%]:not(.high-priority):not(.medium-priority) .review-item-icon[_ngcontent-%COMP%] {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item[_ngcontent-%COMP%]:hover .review-item-action[_ngcontent-%COMP%] {\n color: var(--suite-run-primary);\n}\n\n.review-more[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n\n\n@media (max-width: 768px) {\n .eval-summary-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header[_ngcontent-%COMP%] {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body[_ngcontent-%COMP%] {\n padding: 12px 14px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] {\n padding: 12px 16px;\n }\n\n .needs-review-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 13px;\n }\n\n .review-item[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n\n .review-item-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n\n\n\n\n.feedback-col[_ngcontent-%COMP%] {\n width: 1%; \n\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low[_ngcontent-%COMP%] {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid[_ngcontent-%COMP%] {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high[_ngcontent-%COMP%] {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.correct[_ngcontent-%COMP%] {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness[_ngcontent-%COMP%] i.incorrect[_ngcontent-%COMP%] {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}"], changeDetection: 0 }); }
|
|
2317
2291
|
};
|
|
2318
2292
|
MJTestSuiteRunFormComponentExtended = __decorate([
|
|
2319
2293
|
RegisterClass(BaseFormComponent, 'MJ: Test Suite Runs')
|
|
@@ -2321,7 +2295,7 @@ MJTestSuiteRunFormComponentExtended = __decorate([
|
|
|
2321
2295
|
export { MJTestSuiteRunFormComponentExtended };
|
|
2322
2296
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJTestSuiteRunFormComponentExtended, [{
|
|
2323
2297
|
type: Component,
|
|
2324
|
-
args: [{ standalone: false, selector: 'mj-test-suite-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-run-form\">\n <!-- Header Section -->\n <div class=\"suite-run-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 @if (testSuite) {\n <li>\n <i class=\"fas fa-chevron-right separator\"></i>\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">\n <i class=\"fas fa-layer-group\"></i>\n <span class=\"breadcrumb-text\">{{ testSuite.Name }}</span>\n </a>\n </li>\n }\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </li>\n </ol>\n </nav>\n\n <!-- Header Content -->\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-run-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"suite-run-info\">\n <h1>Suite Run</h1>\n <div class=\"suite-run-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n @if (record.Environment) {\n <span class=\"meta-tag environment\">\n <i class=\"fas fa-server\"></i>\n {{ record.Environment }}\n </span>\n }\n @if (record.TriggerType) {\n <span class=\"meta-tag trigger\">\n <i class=\"fas fa-bolt\"></i>\n {{ record.TriggerType }}\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <!-- Evaluation Mode Toggle -->\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n @if (record.SuiteID) {\n <button mjButton (click)=\"reRunSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Re-run Suite\n </button>\n }\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\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n <div class=\"metric-label\">Duration</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n <div class=\"metric-label\">Pass Rate</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ formatCost(record.TotalCostUSD) }}</div>\n <div class=\"metric-label\">Total Cost</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-calendar\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-label\">Started</div>\n </div>\n </div>\n </div>\n\n <!-- Results Summary -->\n <div class=\"results-summary\">\n <div class=\"result-item passed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-check-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.PassedTests || 0 }}</span>\n <span class=\"result-label\">Passed</span>\n </div>\n </div>\n <div class=\"result-item failed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-times-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.FailedTests || 0 }}</span>\n <span class=\"result-label\">Failed</span>\n </div>\n </div>\n <div class=\"result-item error\">\n <div class=\"result-icon\">\n <i class=\"fas fa-exclamation-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.ErrorTests || 0 }}</span>\n <span class=\"result-label\">Errors</span>\n </div>\n </div>\n <div class=\"result-item skipped\">\n <div class=\"result-icon\">\n <i class=\"fas fa-forward\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.SkippedTests || 0 }}</span>\n <span class=\"result-label\">Skipped</span>\n </div>\n </div>\n <div class=\"result-item total\">\n <div class=\"result-icon\">\n <i class=\"fas fa-list\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.TotalTests || 0 }}</span>\n <span class=\"result-label\">Total</span>\n </div>\n </div>\n </div>\n\n <!-- Tags Section - Sleek inline design -->\n @if (!editingTags) {\n <div class=\"tags-bar\">\n <div class=\"tags-bar-content\">\n <span class=\"tags-bar-label\"><i class=\"fas fa-tags\"></i></span>\n @if (tags.length > 0) {\n <div class=\"tags-bar-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-inline\">{{ tag }}</span>\n }\n </div>\n }\n @if (tags.length === 0) {\n <span class=\"tags-bar-empty\">No tags</span>\n }\n <button class=\"tags-bar-edit\" (click)=\"startEditingTags()\" title=\"Edit tags\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n </div>\n </div>\n }\n\n <!-- Tags Editor - Expanded when editing -->\n @if (editingTags) {\n <div class=\"tags-editor-panel\">\n <div class=\"tags-editor-header\">\n <span class=\"tags-editor-title\"><i class=\"fas fa-tags\"></i> Edit Tags</span>\n </div>\n <div class=\"tags-editor-body\">\n <div class=\"tags-editor-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-editable\">\n {{ tag }}\n <button class=\"tag-remove-btn\" (click)=\"removeTag(tag)\" title=\"Remove tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n @if (tags.length === 0) {\n <span class=\"tags-empty-hint\">No tags yet</span>\n }\n </div>\n <div class=\"tags-editor-input\">\n <input type=\"text\"\n [(ngModel)]=\"newTag\"\n placeholder=\"Type a tag and press Enter...\"\n (keyup.enter)=\"addTag()\"\n class=\"tag-text-input\" />\n <button mjButton (click)=\"addTag()\" [disabled]=\"!newTag.trim()\" variant=\"flat\">\n <i class=\"fas fa-plus\"></i>\n </button>\n </div>\n </div>\n <div class=\"tags-editor-footer\">\n <button mjButton (click)=\"saveTags()\" variant=\"primary\" [disabled]=\"savingTags\">\n @if (savingTags) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n {{ savingTags ? 'Saving...' : 'Save' }}\n </button>\n <button mjButton (click)=\"cancelEditingTags()\" variant=\"flat\">Cancel</button>\n </div>\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 === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-list\"></i> Test Runs\n @if (testRunsLoaded) {\n <span class=\"tab-badge\">{{ testRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'details'\"\n (click)=\"changeTab('details')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'details'\">\n <i class=\"fas fa-info-circle\"></i> Details\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 title=\"Press 4\">\n <i class=\"fas fa-chart-bar\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'execution'\"\n (click)=\"changeTab('execution')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'execution'\"\n title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</span>\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 <!-- Result Hero -->\n <div class=\"result-hero\"\n [class.passed]=\"record.Status === 'Completed' && getPassRate() >= 90\"\n [class.failed]=\"record.Status === 'Failed' || getPassRate() < 50\"\n [class.running]=\"record.Status === 'Running'\"\n [class.pending]=\"record.Status === 'Pending'\">\n <div class=\"result-hero-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"result-hero-text\">\n <h2>SUITE {{ record.Status.toUpperCase() || 'UNKNOWN' }}</h2>\n <div class=\"result-hero-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ getPassRate().toFixed(1) }}%</span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n <div class=\"stat-divider\"></div>\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ record.PassedTests || 0 }} / {{ record.TotalTests || 0 }}</span>\n <span class=\"stat-label\">Tests Passed</span>\n </div>\n </div>\n </div>\n </div>\n <!-- Evaluation Metrics Summary -->\n @if (evaluationMetrics && feedbacksLoaded) {\n <div class=\"evaluation-summary\">\n <div class=\"eval-summary-grid\">\n <!-- Human Feedback Card -->\n @if (evalPreferences.showHuman) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-user\"></i>\n <span>Human Feedback</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Reviewed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanReviewedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n @if (evaluationMetrics.humanReviewedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Avg Rating</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanAvgRating.toFixed(1) }}/10</span>\n </div>\n }\n @if (evaluationMetrics.humanReviewedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Correct</span>\n <span class=\"eval-stat-value correct\">{{ evaluationMetrics.humanCorrectCount }}</span>\n @if (evaluationMetrics.humanIncorrectCount > 0) {\n <span class=\"eval-stat-value incorrect\">{{ evaluationMetrics.humanIncorrectCount }} incorrect</span>\n }\n </div>\n }\n </div>\n @if (evaluationMetrics.humanPendingCount > 0) {\n <div class=\"eval-card-footer\">\n <span class=\"pending-badge\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ evaluationMetrics.humanPendingCount }} need review\n </span>\n </div>\n }\n </div>\n }\n <!-- Auto Score Card -->\n @if (evalPreferences.showAuto) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>Auto Evaluation</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Evaluated</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoEvaluatedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n @if (evaluationMetrics.autoEvaluatedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Avg Score</span>\n <span class=\"eval-stat-value\">{{ (evaluationMetrics.autoAvgScore * 100).toFixed(0) }}%</span>\n </div>\n }\n @if (evaluationMetrics.autoEvaluatedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Pass Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoPassRate.toFixed(0) }}%</span>\n </div>\n }\n </div>\n </div>\n }\n <!-- Execution Card -->\n @if (evalPreferences.showExecution) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>Execution</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Completed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execCompletedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Success Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execSuccessRate.toFixed(0) }}%</span>\n </div>\n @if (evaluationMetrics.execErrorCount > 0 || evaluationMetrics.execTimeoutCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Issues</span>\n @if (evaluationMetrics.execErrorCount > 0) {\n <span class=\"eval-stat-value error\">{{ evaluationMetrics.execErrorCount }} errors</span>\n }\n @if (evaluationMetrics.execTimeoutCount > 0) {\n <span class=\"eval-stat-value timeout\">{{ evaluationMetrics.execTimeoutCount }} timeouts</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Needs Review Section -->\n @if (evalPreferences.showHuman && needsReviewItems.length > 0 && feedbacksLoaded) {\n <div class=\"needs-review-section\">\n <div class=\"needs-review-header\">\n <h3><i class=\"fa-solid fa-user-clock\"></i> Needs Review</h3>\n <span class=\"review-count\">{{ needsReviewItems.length }} items</span>\n </div>\n <div class=\"needs-review-list\">\n @for (item of needsReviewItems.slice(0, 5); track item) {\n <div class=\"review-item\"\n [class.high-priority]=\"item.priority === 'high'\"\n [class.medium-priority]=\"item.priority === 'medium'\"\n (click)=\"toggleRunExpanded(item.run.id)\">\n <div class=\"review-item-icon\">\n @if (item.priority === 'high') {\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n }\n @if (item.priority === 'medium') {\n <i class=\"fa-solid fa-circle-dot\"></i>\n }\n @if (item.priority === 'low') {\n <i class=\"fa-solid fa-clock\"></i>\n }\n </div>\n <div class=\"review-item-content\">\n <span class=\"review-item-name\">{{ item.run.testName }}</span>\n <span class=\"review-item-reason\">{{ item.reason }}</span>\n </div>\n <div class=\"review-item-action\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div>\n </div>\n }\n @if (needsReviewItems.length > 5) {\n <div class=\"review-more\">\n <button mjButton variant=\"flat\" (click)=\"changeTab('runs')\">\n View all {{ needsReviewItems.length }} items\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- Progress Ring (when running) -->\n @if (record.Status === 'Running' || record.Status === 'Pending') {\n <div class=\"progress-section\">\n <div class=\"progress-info\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>Suite execution in progress...</span>\n </div>\n <div class=\"auto-refresh-notice\">\n <i class=\"fas fa-sync\"></i>\n Auto-refreshing every 5 seconds\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Test Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Toolbar -->\n @if (testRunsLoaded && testRuns.length > 0) {\n <div class=\"runs-toolbar\">\n <div class=\"run-filters\">\n <button class=\"filter-btn\"\n [class.active]=\"runStatusFilter === null\"\n (click)=\"setRunStatusFilter(null)\">\n All ({{ testRuns.length }})\n </button>\n @if (getRunCountByStatus('Passed') > 0) {\n <button class=\"filter-btn passed\"\n [class.active]=\"runStatusFilter === 'Passed'\"\n (click)=\"setRunStatusFilter('Passed')\"\n >\n <i class=\"fas fa-check\"></i> Passed ({{ getRunCountByStatus('Passed') }})\n </button>\n }\n @if (getRunCountByStatus('Failed') > 0) {\n <button class=\"filter-btn failed\"\n [class.active]=\"runStatusFilter === 'Failed'\"\n (click)=\"setRunStatusFilter('Failed')\"\n >\n <i class=\"fas fa-times\"></i> Failed ({{ getRunCountByStatus('Failed') }})\n </button>\n }\n @if (getRunCountByStatus('Error') > 0) {\n <button class=\"filter-btn error\"\n [class.active]=\"runStatusFilter === 'Error'\"\n (click)=\"setRunStatusFilter('Error')\"\n >\n <i class=\"fas fa-exclamation\"></i> Error ({{ getRunCountByStatus('Error') }})\n </button>\n }\n </div>\n <div class=\"runs-actions\">\n <button mjButton (click)=\"exportToCSV()\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n }\n <!-- Loading State -->\n @if (loadingTestRuns) {\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 <!-- Test Runs List -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"test-runs-list\">\n @for (run of getFilteredTestRuns(); track run) {\n <div class=\"test-run-card\">\n <div class=\"test-run-item\" (click)=\"toggleRunExpanded(run.ID)\">\n <div class=\"run-sequence\">{{ run.Sequence || '-' }}</div>\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\" [ngClass]=\"getRunStatusIcon(run.Status)\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header-row\">\n <div class=\"run-name\">{{ run.Test }}</div>\n <!-- Evaluation Badge -->\n <app-evaluation-badge\n [executionStatus]=\"run.Status\"\n [originalStatus]=\"run.Status\"\n [autoScore]=\"run.Score\"\n [humanRating]=\"getFeedbackRating(run.ID) || null\"\n [humanIsCorrect]=\"getHumanIsCorrect(run.ID)\"\n [hasHumanFeedback]=\"hasFeedback(run.ID)\"\n [preferences]=\"evalPreferences\"\n [mode]=\"'compact'\">\n </app-evaluation-badge>\n </div>\n <div class=\"run-meta\">\n @if (run.DurationSeconds) {\n <span class=\"run-duration\">\n <i class=\"fas fa-clock\"></i> {{ run.DurationSeconds.toFixed(1) }}s\n </span>\n }\n @if (run.CostUSD) {\n <span class=\"run-cost\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.CostUSD.toFixed(6) }}\n </span>\n }\n @if (run.TargetLogEntityID && run.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"run.TargetLogEntity\"\n [recordId]=\"run.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\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 <div class=\"run-expand\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedRunId !== run.ID\" [class.fa-chevron-up]=\"expandedRunId === run.ID\"></i>\n </div>\n </div>\n <!-- Expanded Inline Feedback -->\n @if (expandedRunId === run.ID) {\n <div class=\"inline-feedback\">\n <div class=\"feedback-divider\"></div>\n <div class=\"feedback-section\">\n <div class=\"feedback-label\">Quick Feedback</div>\n <div class=\"inline-rating\">\n <div class=\"rating-numbers\">\n @for (num of [1,2,3,4,5,6,7,8,9,10]; track num) {\n <button\n type=\"button\"\n class=\"rating-btn\"\n [class.selected]=\"num === inlineRating\"\n [class.hover]=\"num === inlineHoverRating\"\n [class.low]=\"num <= 3\"\n [class.mid]=\"num >= 4 && num <= 6\"\n [class.high]=\"num >= 7\"\n (click)=\"setInlineRating(num); $event.stopPropagation()\"\n (mouseenter)=\"inlineHoverRating = num\"\n (mouseleave)=\"inlineHoverRating = 0\">\n {{ num }}\n </button>\n }\n </div>\n @if (inlineRating > 0) {\n <div class=\"rating-info\">\n <span class=\"rating-value\">{{ inlineRating }}/10</span>\n <span class=\"rating-label-text\">{{ getInlineRatingLabel() }}</span>\n </div>\n }\n </div>\n <div class=\"correctness-row\">\n <span class=\"correctness-label\">Was it correct?</span>\n <div class=\"correctness-options\">\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"true\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Yes</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"false\" [(ngModel)]=\"inlineIsCorrect\">\n <span>No</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"null\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Not Sure</span>\n </label>\n </div>\n </div>\n <div class=\"comments-row\" (click)=\"$event.stopPropagation()\">\n <textarea\n class=\"feedback-textarea\"\n [(ngModel)]=\"inlineComments\"\n placeholder=\"Add comments or corrections...\"\n rows=\"3\"></textarea>\n </div>\n <div class=\"feedback-actions\" (click)=\"$event.stopPropagation()\">\n <button mjButton (click)=\"openTestRun(run.ID)\">\n <i class=\"fas fa-external-link-alt\"></i> View Full Details\n </button>\n <button mjButton\n variant=\"primary\"\n (click)=\"saveInlineFeedback()\"\n [disabled]=\"!canSubmitInlineFeedback() || savingInlineFeedback\">\n <i class=\"fas\" [ngClass]=\"savingInlineFeedback ? 'fa-spinner fa-spin' : 'fa-save'\"></i>\n {{ savingInlineFeedback ? 'Saving...' : (hasFeedback(run.ID) ? 'Update' : 'Save') }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testRunsLoaded && !loadingTestRuns && testRuns.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-inbox\"></i>\n </div>\n <h4>No Test Runs Found</h4>\n <p>No test runs have been recorded for this suite execution.</p>\n </div>\n }\n <!-- Filtered Empty -->\n @if (testRunsLoaded && !loadingTestRuns && testRuns.length > 0 && getFilteredTestRuns().length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-filter\"></i>\n </div>\n <h4>No Matching Runs</h4>\n <p>No test runs match the current filter.</p>\n <button mjButton (click)=\"setRunStatusFilter(null)\">Clear Filter</button>\n </div>\n }\n </div>\n }\n\n <!-- Details Tab -->\n @if (activeTab === 'details') {\n <div class=\"details-tab\">\n <div class=\"details-card\">\n <h3><i class=\"fas fa-info-circle\"></i> Run Information</h3>\n <div class=\"details-grid\">\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test Suite</div>\n <div class=\"detail-value\">\n @if (testSuite) {\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">{{ testSuite.Name }}</a>\n }\n @if (!testSuite) {\n <span>Loading...</span>\n }\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Status</div>\n <div class=\"detail-value\">\n <span class=\"status-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run By</div>\n <div class=\"detail-value\">{{ record.RunByUser || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Environment</div>\n <div class=\"detail-value\">{{ record.Environment || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Trigger Type</div>\n <div class=\"detail-value\">{{ record.TriggerType || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Git Commit</div>\n <div class=\"detail-value monospace\">{{ record.GitCommit || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Agent Version</div>\n <div class=\"detail-value\">{{ record.AgentVersion || 'N/A' }}</div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingTestRuns) {\n <div class=\"analytics-loading\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading test results...</span>\n </div>\n }\n <!-- Summary Statistics - Moved to top for better overview -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"analytics-section\">\n <h3><i class=\"fas fa-chart-pie\"></i> Summary Statistics</h3>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon passed\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getPassedCount() }}</div>\n <div class=\"stat-label\">Passed</div>\n <div class=\"stat-percent\">{{ getPassedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon failed\"><i class=\"fas fa-times-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getFailedCount() }}</div>\n <div class=\"stat-label\">Failed</div>\n <div class=\"stat-percent\">{{ getFailedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon score\"><i class=\"fas fa-star\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ (getAverageScore() * 100).toFixed(1) }}%</div>\n <div class=\"stat-label\">Avg Score</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon duration\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getAverageDuration().toFixed(1) }}s</div>\n <div class=\"stat-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon cost\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">${{ getTotalCost().toFixed(4) }}</div>\n <div class=\"stat-label\">Total Cost</div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Test Results Table -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"analytics-section\">\n <div class=\"analytics-header\">\n <h3><i class=\"fas fa-table\"></i> Test Results</h3>\n <div class=\"analytics-legend\">\n <span class=\"legend-item passed\"><i class=\"fas fa-check-circle\"></i> Passed</span>\n <span class=\"legend-item failed\"><i class=\"fas fa-times-circle\"></i> Failed</span>\n <span class=\"legend-item error\"><i class=\"fas fa-exclamation-circle\"></i> Error</span>\n <span class=\"legend-item skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <!-- Results Table -->\n <div class=\"results-table-wrapper\">\n <table class=\"results-table\">\n <thead>\n <tr>\n <th class=\"seq-col\">#</th>\n <th class=\"name-col\">Test Name</th>\n @if (evalPreferences.showExecution) {\n <th class=\"status-col\">Status</th>\n }\n @if (evalPreferences.showAuto) {\n <th class=\"score-col\">Auto Score</th>\n }\n @if (evalPreferences.showHuman) {\n <th class=\"feedback-col\">Human Score</th>\n }\n <th class=\"duration-col\">Duration</th>\n <th class=\"cost-col\">Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (run of testRuns; track run; let i = $index) {\n <tr\n class=\"result-row\"\n [class.row-passed]=\"run.Status === 'Passed'\"\n [class.row-failed]=\"run.Status === 'Failed'\"\n [class.row-error]=\"run.Status === 'Error'\"\n [class.row-skipped]=\"run.Status === 'Skipped'\"\n (click)=\"openTestRun(run.ID)\">\n <td class=\"seq-col\">{{ i + 1 }}</td>\n <td class=\"name-col\">\n <div class=\"test-name-wrapper\">\n <span class=\"test-name\">{{ run.Test || 'Unknown Test' }}</span>\n @if (getRunTags(run).length > 0) {\n <div class=\"test-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 </td>\n @if (evalPreferences.showExecution) {\n <td class=\"status-col\">\n <span class=\"status-badge\" [ngClass]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-check-circle]=\"run.Status === 'Passed'\"\n [class.fa-times-circle]=\"run.Status === 'Failed'\"\n [class.fa-exclamation-circle]=\"run.Status === 'Error'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-spin]=\"run.Status === 'Running'\"></i>\n {{ run.Status }}\n </span>\n </td>\n }\n @if (evalPreferences.showAuto) {\n <td class=\"score-col\">\n @if (run.Score != null) {\n <div class=\"score-display\">\n <div class=\"score-bar-mini\">\n <div class=\"score-fill\"\n [style.width.%]=\"run.Score * 100\"\n [class.high]=\"run.Score >= 0.8\"\n [class.medium]=\"run.Score >= 0.5 && run.Score < 0.8\"\n [class.low]=\"run.Score < 0.5\"></div>\n </div>\n <span class=\"score-text\">{{ (run.Score * 100).toFixed(0) }}%</span>\n </div>\n }\n @if (run.Score == null) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n }\n @if (evalPreferences.showHuman) {\n <td class=\"feedback-col\">\n @if (hasFeedback(run.ID)) {\n <div class=\"feedback-display\">\n <span class=\"feedback-rating\" [class.low]=\"getFeedbackRating(run.ID) <= 3\" [class.mid]=\"getFeedbackRating(run.ID) >= 4 && getFeedbackRating(run.ID) <= 6\" [class.high]=\"getFeedbackRating(run.ID) >= 7\">\n {{ getFeedbackRating(run.ID) }}/10\n </span>\n @if (getHumanIsCorrect(run.ID) !== null) {\n <span class=\"feedback-correctness\">\n <i class=\"fas\" [class.fa-check]=\"getHumanIsCorrect(run.ID) === true\" [class.fa-times]=\"getHumanIsCorrect(run.ID) === false\" [class.correct]=\"getHumanIsCorrect(run.ID) === true\" [class.incorrect]=\"getHumanIsCorrect(run.ID) === false\"></i>\n </span>\n }\n </div>\n }\n @if (!hasFeedback(run.ID)) {\n <span class=\"na-value needs-review\">\n <i class=\"fas fa-user-clock\"></i>\n </span>\n }\n </td>\n }\n <td class=\"duration-col\">\n @if (run.DurationSeconds) {\n <span>{{ run.DurationSeconds.toFixed(1) }}s</span>\n }\n @if (!run.DurationSeconds) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n <td class=\"cost-col\">\n @if (run.CostUSD) {\n <span>${{ run.CostUSD.toFixed(4) }}</span>\n }\n @if (!run.CostUSD) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (!loadingTestRuns && testRunsLoaded && testRuns.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-chart-bar\"></i>\n </div>\n <h4>No Test Results Yet</h4>\n <p>Test runs will appear here once the suite execution completes.</p>\n </div>\n }\n </div>\n }\n\n <!-- Execution Tab -->\n @if (activeTab === 'execution') {\n <div class=\"execution-tab\">\n <mj-execution-context\n [machineName]=\"record.MachineName\"\n [machineId]=\"record.MachineID\"\n [runByUserName]=\"record.RunByUserName\"\n [runByUserEmail]=\"record.RunByUserEmail\"\n [runContextDetailsJson]=\"record.RunContextDetails\">\n </mj-execution-context>\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>Re-run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Shift</kbd><kbd>R</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</div>\n", styles: ["/* ===================================\n Test Suite Run Form - Premium UX\n World-class responsive design\n =================================== */\n\n/* CSS Custom Properties */\n:host {\n --suite-run-primary: var(--mj-brand-primary);\n --suite-run-primary-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-success: var(--mj-status-success);\n --suite-run-success-light: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n --suite-run-danger: var(--mj-status-error);\n --suite-run-danger-light: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n --suite-run-warning: var(--mj-status-warning);\n --suite-run-warning-light: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --suite-run-info: var(--mj-brand-primary);\n --suite-run-info-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-neutral: var(--mj-text-muted);\n --suite-run-neutral-light: var(--mj-bg-surface-card);\n --suite-run-bg: var(--mj-bg-surface-card);\n --suite-run-card: var(--mj-bg-surface);\n --suite-run-border: var(--mj-border-default);\n --suite-run-text: var(--mj-text-primary);\n --suite-run-text-secondary: var(--mj-text-muted);\n --suite-run-radius: 12px;\n --suite-run-shadow: var(--mj-shadow-sm);\n --suite-run-shadow-lg: var(--mj-shadow-lg);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* Base Container */\n.test-suite-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n/* ===================================\n Header Section\n =================================== */\n.suite-run-header {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\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(--suite-run-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(--suite-run-text-secondary);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--suite-run-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 Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info h1 {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* ===================================\n Metrics Bar\n =================================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.metric-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.metric-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n/* ===================================\n Results Summary\n =================================== */\n.results-summary {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon {\n font-size: 24px;\n}\n\n.result-content {\n display: flex;\n flex-direction: column;\n}\n\n.result-count {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed .result-icon,\n.result-item.passed .result-count {\n color: var(--suite-run-success);\n}\n\n.result-item.failed .result-icon,\n.result-item.failed .result-count {\n color: var(--suite-run-danger);\n}\n\n.result-item.error .result-icon,\n.result-item.error .result-count {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped .result-icon,\n.result-item.skipped .result-count {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total .result-icon,\n.result-item.total .result-count {\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Tabs\n =================================== */\n.tabs-container {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--suite-run-border);\n color: var(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n/* ===================================\n Tab Content\n =================================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* ===================================\n Overview Tab\n =================================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed .result-hero-icon {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed .result-hero-icon {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running .result-hero-icon {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending .result-hero-icon {\n color: var(--suite-run-info);\n}\n\n.result-hero-text h2 {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n/* Progress Section */\n.progress-section {\n background: var(--suite-run-primary-light);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info i {\n font-size: 20px;\n}\n\n.auto-refresh-notice {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* ===================================\n Test Runs Tab\n =================================== */\n.runs-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n/* Loading Skeleton */\n.loading-state {\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide {\n width: 70%;\n}\n\n.skeleton-line.narrow {\n width: 40%;\n}\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Test Runs List */\n.test-runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateX(4px);\n}\n\n.test-run-item:active {\n transform: translateX(2px);\n}\n\n.run-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status {\n font-weight: 700;\n}\n\n.run-score,\n.run-duration {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score i,\n.run-duration i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item > i {\n color: var(--mj-border-strong);\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover > i {\n color: var(--suite-run-primary);\n transform: translateX(4px);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n text-align: center;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 2px dashed var(--suite-run-border);\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(--suite-run-neutral-light);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 32px;\n color: var(--mj-border-strong);\n}\n\n.empty-state h4 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--suite-run-text-secondary);\n max-width: 300px;\n}\n\n/* ===================================\n Details Tab\n =================================== */\n.details-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card h3 i {\n color: var(--suite-run-primary);\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value a {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value a:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.status-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n/* ===================================\n Keyboard Shortcuts\n =================================== */\n/* 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(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts:hover {\n opacity: 1;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header i {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-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 gap: 16px;\n}\n\n.shortcut-item span:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\nkbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 var(--mj-text-disabled);\n}\n\n/* ===================================\n Responsive Design - Tablet\n =================================== */\n@media (max-width: 1024px) {\n .suite-run-header {\n padding: 16px 20px;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider {\n display: none;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Mobile\n =================================== */\n@media (max-width: 768px) {\n .suite-run-header {\n padding: 16px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .suite-run-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info h1 {\n font-size: 20px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 8px;\n }\n\n .metric-card {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .results-summary {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon {\n font-size: 20px;\n }\n\n .result-count {\n font-size: 18px;\n }\n\n .tabs {\n padding: 0 16px;\n }\n\n .tab {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 32px 20px;\n }\n\n .result-hero-icon {\n font-size: 56px;\n }\n\n .result-hero-text h2 {\n font-size: 24px;\n }\n\n .stat-value {\n font-size: 20px;\n }\n\n .test-run-item {\n padding: 14px;\n }\n\n .run-sequence {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name {\n font-size: 13px;\n }\n\n .run-meta {\n gap: 10px;\n font-size: 11px;\n }\n\n .empty-state {\n padding: 40px 16px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n\n .details-card {\n padding: 16px;\n }\n\n .details-grid {\n gap: 16px;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Small Mobile\n =================================== */\n@media (max-width: 480px) {\n .suite-run-header {\n padding: 12px;\n }\n\n .breadcrumb {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info h1 {\n font-size: 18px;\n }\n\n .suite-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .meta-tag {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .result-item {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon {\n font-size: 18px;\n }\n\n .result-count {\n font-size: 16px;\n }\n\n .result-label {\n font-size: 9px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 24px 16px;\n }\n\n .result-hero-icon {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text h2 {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value {\n font-size: 18px;\n }\n\n .stat-label {\n font-size: 10px;\n }\n\n .progress-section {\n padding: 16px;\n }\n\n .progress-info {\n font-size: 14px;\n }\n\n .test-run-item {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta {\n gap: 8px;\n font-size: 10px;\n }\n\n .empty-state {\n padding: 32px 12px;\n }\n\n .empty-state h4 {\n font-size: 16px;\n }\n\n .empty-state p {\n font-size: 13px;\n }\n\n .details-card {\n padding: 14px;\n }\n\n .details-card h3 {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label {\n font-size: 10px;\n }\n\n .detail-value {\n font-size: 13px;\n }\n}\n\n/* ===================================\n Touch Device Optimizations\n =================================== */\n@media (hover: none) and (pointer: coarse) {\n .test-run-item {\n min-height: 64px;\n }\n\n .test-run-item:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item:active {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n\n .tab:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts {\n display: none;\n }\n}\n\n/* ===================================\n Print Styles\n =================================== */\n@media print {\n .suite-run-header {\n background: var(--mj-bg-surface);\n box-shadow: none;\n border-bottom: 2px solid var(--mj-text-primary);\n }\n\n .tabs-container,\n .header-actions,\n .keyboard-shortcuts {\n display: none;\n }\n\n .tab-content {\n padding: 20px 0;\n }\n\n .result-hero,\n .test-run-item,\n .details-card {\n box-shadow: none;\n border: 1px solid var(--mj-border-strong);\n }\n}\n\n/* ===================================\n Dark Mode Support (Future)\n =================================== */\n@media (prefers-color-scheme: dark) {\n /* Ready for dark mode implementation */\n}\n\n/* ===================================\n Tags Bar - Sleek Inline Display\n =================================== */\n.tags-bar {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label {\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label i {\n opacity: 0.6;\n}\n\n.tags-bar-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tags-bar-edit i {\n font-size: 10px;\n}\n\n/* ===================================\n Tags Editor Panel - Expanded Edit Mode\n =================================== */\n.tags-editor-panel {\n margin-top: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--suite-run-primary-light);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input::placeholder {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* ===================================\n Runs Toolbar\n =================================== */\n.runs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.passed:hover,\n.filter-btn.passed.active {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.failed:hover,\n.filter-btn.failed.active {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.error:hover,\n.filter-btn.error.active {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.runs-actions {\n display: flex;\n gap: 8px;\n}\n\n/* ===================================\n Test Run Card (Expandable)\n =================================== */\n.test-run-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator i {\n font-size: 10px;\n}\n\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\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) 10%, 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.run-expand {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover .run-expand {\n color: var(--suite-run-primary);\n}\n\n.run-cost {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n/* ===================================\n Inline Feedback\n =================================== */\n.inline-feedback {\n padding: 0 16px 16px;\n animation: slideDown 0.2s ease-out;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn:hover,\n.rating-btn.hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.low:hover,\n.rating-btn.low.hover {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid:hover,\n.rating-btn.mid.hover {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high:hover,\n.rating-btn.high.hover {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.selected.low {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.mid {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.high {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.rating-info {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt input[type=\"radio\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row {\n width: 100%;\n}\n\n.feedback-textarea {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.feedback-actions {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\n/* ===================================\n Mobile Responsive Updates\n =================================== */\n@media (max-width: 768px) {\n .tags-bar {\n padding: 8px 12px;\n }\n\n .tags-bar-content {\n gap: 8px;\n }\n\n .tag-inline {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel {\n margin-top: 12px;\n }\n\n .tags-editor-body {\n padding: 12px;\n }\n\n .tags-editor-footer {\n padding: 10px 12px;\n }\n\n .runs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters {\n justify-content: center;\n }\n\n .runs-actions {\n justify-content: center;\n }\n\n .rating-numbers {\n justify-content: center;\n }\n\n .rating-btn {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions {\n flex-direction: column;\n }\n\n .feedback-actions button {\n width: 100%;\n }\n}\n\n/* ===================================\n Animations\n =================================== */\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running .result-hero-icon {\n animation: pulse 2s ease-in-out infinite;\n}\n\n/* Tab content fade in */\n.overview-tab,\n.runs-tab,\n.details-tab,\n.analytics-tab {\n animation: fadeIn 0.3s ease;\n}\n\n/* ===================================\n Analytics Tab\n =================================== */\n.analytics-tab {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section h3 i {\n color: var(--suite-run-primary);\n}\n\n.analytics-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: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header h3 {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped {\n color: var(--suite-run-neutral);\n}\n\n/* Performance Matrix */\n.performance-matrix {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row:last-child {\n border-bottom: none;\n}\n\n.matrix-row:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell {\n gap: 12px;\n}\n\n.test-sequence {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running {\n color: var(--suite-run-primary);\n}\n\n.score-bar {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high {\n background: var(--suite-run-success);\n}\n\n.score-fill.medium {\n background: var(--suite-run-warning);\n}\n\n.score-fill.low {\n background: var(--suite-run-danger);\n}\n\n.score-text {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n/* Summary Statistics Grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card .stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card .stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* Responsive Analytics */\n@media (max-width: 768px) {\n .analytics-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row {\n display: none;\n }\n\n .matrix-cell {\n padding: 4px 0;\n }\n\n .test-name-cell::before,\n .status-cell::before,\n .score-cell::before,\n .duration-cell::before,\n .cost-cell::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell::before { content: 'Status:'; }\n .score-cell::before { content: 'Score:'; }\n .duration-cell::before { content: 'Duration:'; }\n .cost-cell::before { content: 'Cost:'; }\n\n .stats-grid {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card {\n padding: 16px;\n }\n\n .stat-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card .stat-value {\n font-size: 20px;\n }\n}\n\n/* Focus States for Accessibility */\n.tab:focus-visible,\n.test-run-item:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n/* ===================================\n Analytics Loading State\n =================================== */\n.analytics-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading i {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Results Table\n =================================== */\n.results-table-wrapper {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table thead {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table th {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n vertical-align: middle;\n}\n\n.results-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n/* Column widths - Fixed columns fit content, name column takes remainder (max 50%) */\n.seq-col {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col {\n /* Take remaining space, but cap at 50% of table width */\n width: auto;\n max-width: 50%;\n}\n\n.status-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n}\n\n.score-col {\n width: 1%; /* Shrink to fit content */\n min-width: 120px; /* Score bar needs some minimum width */\n white-space: nowrap;\n}\n\n.duration-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n/* Result Row */\n.result-row {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n/* Test Name Wrapper */\n.test-name-wrapper {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper .test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n/* Score Display */\n.score-display {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini .score-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini .score-fill.high {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini .score-fill.medium {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini .score-fill.low {\n background: var(--suite-run-danger);\n}\n\n.score-display .score-text {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n/* Status Badge in Table */\n.results-table .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table .status-badge.status-passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table .status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table .status-badge.status-error {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table .status-badge.status-skipped {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table .status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table .status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n/* Responsive Results Table */\n@media (max-width: 768px) {\n .results-table-wrapper {\n overflow-x: auto;\n }\n\n .results-table {\n min-width: 600px;\n }\n\n .results-table th,\n .results-table td {\n padding: 10px 12px;\n }\n\n .name-col {\n min-width: 150px;\n }\n}\n\n/* ===================================\n High Contrast Mode\n =================================== */\n@media (prefers-contrast: high) {\n .status-badge,\n .status-inline {\n border: 2px solid currentColor;\n }\n\n .test-run-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===================================\n Evaluation Summary\n =================================== */\n.evaluation-summary {\n margin-top: 20px;\n}\n\n.eval-summary-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header i {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n}\n\n.pending-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge i {\n font-size: 11px;\n}\n\n/* ===================================\n Needs Review Section\n =================================== */\n.needs-review-section {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.needs-review-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-warning);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header h3 i {\n font-size: 16px;\n}\n\n.review-count {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-warning);\n background: color-mix(in srgb, var(--mj-bg-surface) 60%, transparent);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list {\n padding: 8px;\n}\n\n.review-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority .review-item-icon {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority .review-item-icon {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item:not(.high-priority):not(.medium-priority) .review-item-icon {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item:hover .review-item-action {\n color: var(--suite-run-primary);\n}\n\n.review-more {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* Mobile Responsive for Evaluation */\n@media (max-width: 768px) {\n .eval-summary-grid {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body {\n padding: 12px 14px;\n }\n\n .needs-review-header {\n padding: 12px 16px;\n }\n\n .needs-review-header h3 {\n font-size: 13px;\n }\n\n .review-item {\n padding: 10px 12px;\n }\n\n .review-item-icon {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n/* ===================================\n Feedback Column in Analytics Table\n =================================== */\n.feedback-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i {\n font-size: 12px;\n}\n\n.feedback-correctness i.correct {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i.incorrect {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review i {\n font-size: 14px;\n}\n"] }]
|
|
2298
|
+
args: [{ standalone: false, selector: 'mj-test-suite-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-suite-run-form\">\n <!-- Header Section -->\n <div class=\"suite-run-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 @if (testSuite) {\n <li>\n <i class=\"fas fa-chevron-right separator\"></i>\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">\n <i class=\"fas fa-layer-group\"></i>\n <span class=\"breadcrumb-text\">{{ testSuite.Name }}</span>\n </a>\n </li>\n }\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </li>\n </ol>\n </nav>\n\n <!-- Header Content -->\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"suite-run-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"suite-run-info\">\n <h1>Suite Run</h1>\n <div class=\"suite-run-meta\">\n <span class=\"status-badge\" [ngClass]=\"getStatusClass()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n @if (record.Environment) {\n <span class=\"meta-tag environment\">\n <i class=\"fas fa-server\"></i>\n {{ record.Environment }}\n </span>\n }\n @if (record.TriggerType) {\n <span class=\"meta-tag trigger\">\n <i class=\"fas fa-bolt\"></i>\n {{ record.TriggerType }}\n </span>\n }\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <!-- Evaluation Mode Toggle -->\n <app-evaluation-mode-toggle></app-evaluation-mode-toggle>\n @if (record.SuiteID) {\n <button mjButton (click)=\"reRunSuite()\" variant=\"primary\">\n <i class=\"fas fa-play\"></i> Re-run Suite\n </button>\n }\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\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n <div class=\"metric-label\">Duration</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-percentage\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getPassRate().toFixed(1) }}%</div>\n <div class=\"metric-label\">Pass Rate</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ formatCost(record.TotalCostUSD) }}</div>\n <div class=\"metric-label\">Total Cost</div>\n </div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-calendar\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-label\">Started</div>\n </div>\n </div>\n </div>\n\n <!-- Results Summary -->\n <div class=\"results-summary\">\n <div class=\"result-item passed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-check-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.PassedTests || 0 }}</span>\n <span class=\"result-label\">Passed</span>\n </div>\n </div>\n <div class=\"result-item failed\">\n <div class=\"result-icon\">\n <i class=\"fas fa-times-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.FailedTests || 0 }}</span>\n <span class=\"result-label\">Failed</span>\n </div>\n </div>\n <div class=\"result-item error\">\n <div class=\"result-icon\">\n <i class=\"fas fa-exclamation-circle\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.ErrorTests || 0 }}</span>\n <span class=\"result-label\">Errors</span>\n </div>\n </div>\n <div class=\"result-item skipped\">\n <div class=\"result-icon\">\n <i class=\"fas fa-forward\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.SkippedTests || 0 }}</span>\n <span class=\"result-label\">Skipped</span>\n </div>\n </div>\n <div class=\"result-item total\">\n <div class=\"result-icon\">\n <i class=\"fas fa-list\"></i>\n </div>\n <div class=\"result-content\">\n <span class=\"result-count\">{{ record.TotalTests || 0 }}</span>\n <span class=\"result-label\">Total</span>\n </div>\n </div>\n </div>\n\n <!-- Tags Section - Sleek inline design -->\n @if (!editingTags) {\n <div class=\"tags-bar\">\n <div class=\"tags-bar-content\">\n <span class=\"tags-bar-label\"><i class=\"fas fa-tags\"></i></span>\n @if (tags.length > 0) {\n <div class=\"tags-bar-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-inline\">{{ tag }}</span>\n }\n </div>\n }\n @if (tags.length === 0) {\n <span class=\"tags-bar-empty\">No tags</span>\n }\n <button class=\"tags-bar-edit\" (click)=\"startEditingTags()\" title=\"Edit tags\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n </div>\n </div>\n }\n\n <!-- Tags Editor - Expanded when editing -->\n @if (editingTags) {\n <div class=\"tags-editor-panel\">\n <div class=\"tags-editor-header\">\n <span class=\"tags-editor-title\"><i class=\"fas fa-tags\"></i> Edit Tags</span>\n </div>\n <div class=\"tags-editor-body\">\n <div class=\"tags-editor-chips\">\n @for (tag of tags; track tag) {\n <span class=\"tag-editable\">\n {{ tag }}\n <button class=\"tag-remove-btn\" (click)=\"removeTag(tag)\" title=\"Remove tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n }\n @if (tags.length === 0) {\n <span class=\"tags-empty-hint\">No tags yet</span>\n }\n </div>\n <div class=\"tags-editor-input\">\n <input type=\"text\"\n [(ngModel)]=\"newTag\"\n placeholder=\"Type a tag and press Enter...\"\n (keyup.enter)=\"addTag()\"\n class=\"tag-text-input\" />\n <button mjButton (click)=\"addTag()\" [disabled]=\"!newTag.trim()\" variant=\"flat\">\n <i class=\"fas fa-plus\"></i>\n </button>\n </div>\n </div>\n <div class=\"tags-editor-footer\">\n <button mjButton (click)=\"saveTags()\" variant=\"primary\" [disabled]=\"savingTags\">\n @if (savingTags) {\n <i class=\"fas fa-spinner fa-spin\"></i>\n }\n {{ savingTags ? 'Saving...' : 'Save' }}\n </button>\n <button mjButton (click)=\"cancelEditingTags()\" variant=\"flat\">Cancel</button>\n </div>\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 === 'runs'\"\n (click)=\"changeTab('runs')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'runs'\">\n <i class=\"fas fa-list\"></i> Test Runs\n @if (testRunsLoaded) {\n <span class=\"tab-badge\">{{ testRuns.length }}</span>\n }\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'details'\"\n (click)=\"changeTab('details')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'details'\">\n <i class=\"fas fa-info-circle\"></i> Details\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 title=\"Press 4\">\n <i class=\"fas fa-chart-bar\"></i> Analytics\n </button>\n <button class=\"tab\"\n [class.active]=\"activeTab === 'execution'\"\n (click)=\"changeTab('execution')\"\n role=\"tab\"\n [attr.aria-selected]=\"activeTab === 'execution'\"\n title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</span>\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 <!-- Result Hero -->\n <div class=\"result-hero\"\n [class.passed]=\"record.Status === 'Completed' && getPassRate() >= 90\"\n [class.failed]=\"record.Status === 'Failed' || getPassRate() < 50\"\n [class.running]=\"record.Status === 'Running'\"\n [class.pending]=\"record.Status === 'Pending'\">\n <div class=\"result-hero-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"result-hero-text\">\n <h2>SUITE {{ record.Status.toUpperCase() || 'UNKNOWN' }}</h2>\n <div class=\"result-hero-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ getPassRate().toFixed(1) }}%</span>\n <span class=\"stat-label\">Pass Rate</span>\n </div>\n <div class=\"stat-divider\"></div>\n <div class=\"stat-item\">\n <span class=\"stat-value\">{{ record.PassedTests || 0 }} / {{ record.TotalTests || 0 }}</span>\n <span class=\"stat-label\">Tests Passed</span>\n </div>\n </div>\n </div>\n </div>\n <!-- Evaluation Metrics Summary -->\n @if (evaluationMetrics && feedbacksLoaded) {\n <div class=\"evaluation-summary\">\n <div class=\"eval-summary-grid\">\n <!-- Human Feedback Card -->\n @if (evalPreferences.showHuman) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-user\"></i>\n <span>Human Feedback</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Reviewed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanReviewedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n @if (evaluationMetrics.humanReviewedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Avg Rating</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.humanAvgRating.toFixed(1) }}/10</span>\n </div>\n }\n @if (evaluationMetrics.humanReviewedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Correct</span>\n <span class=\"eval-stat-value correct\">{{ evaluationMetrics.humanCorrectCount }}</span>\n @if (evaluationMetrics.humanIncorrectCount > 0) {\n <span class=\"eval-stat-value incorrect\">{{ evaluationMetrics.humanIncorrectCount }} incorrect</span>\n }\n </div>\n }\n </div>\n @if (evaluationMetrics.humanPendingCount > 0) {\n <div class=\"eval-card-footer\">\n <span class=\"pending-badge\">\n <i class=\"fa-solid fa-clock\"></i>\n {{ evaluationMetrics.humanPendingCount }} need review\n </span>\n </div>\n }\n </div>\n }\n <!-- Auto Score Card -->\n @if (evalPreferences.showAuto) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-robot\"></i>\n <span>Auto Evaluation</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Evaluated</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoEvaluatedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n @if (evaluationMetrics.autoEvaluatedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Avg Score</span>\n <span class=\"eval-stat-value\">{{ (evaluationMetrics.autoAvgScore * 100).toFixed(0) }}%</span>\n </div>\n }\n @if (evaluationMetrics.autoEvaluatedCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Pass Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.autoPassRate.toFixed(0) }}%</span>\n </div>\n }\n </div>\n </div>\n }\n <!-- Execution Card -->\n @if (evalPreferences.showExecution) {\n <div class=\"eval-summary-card\">\n <div class=\"eval-card-header\">\n <i class=\"fa-solid fa-circle-check\"></i>\n <span>Execution</span>\n </div>\n <div class=\"eval-card-body\">\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Completed</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execCompletedCount }} / {{ evaluationMetrics.totalRuns }}</span>\n </div>\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Success Rate</span>\n <span class=\"eval-stat-value\">{{ evaluationMetrics.execSuccessRate.toFixed(0) }}%</span>\n </div>\n @if (evaluationMetrics.execErrorCount > 0 || evaluationMetrics.execTimeoutCount > 0) {\n <div class=\"eval-stat-row\">\n <span class=\"eval-stat-label\">Issues</span>\n @if (evaluationMetrics.execErrorCount > 0) {\n <span class=\"eval-stat-value error\">{{ evaluationMetrics.execErrorCount }} errors</span>\n }\n @if (evaluationMetrics.execTimeoutCount > 0) {\n <span class=\"eval-stat-value timeout\">{{ evaluationMetrics.execTimeoutCount }} timeouts</span>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Needs Review Section -->\n @if (evalPreferences.showHuman && needsReviewItems.length > 0 && feedbacksLoaded) {\n <div class=\"needs-review-section\">\n <div class=\"needs-review-header\">\n <h3><i class=\"fa-solid fa-user-clock\"></i> Needs Review</h3>\n <span class=\"review-count\">{{ needsReviewItems.length }} items</span>\n </div>\n <div class=\"needs-review-list\">\n @for (item of needsReviewItems.slice(0, 5); track item) {\n <div class=\"review-item\"\n [class.high-priority]=\"item.priority === 'high'\"\n [class.medium-priority]=\"item.priority === 'medium'\"\n (click)=\"toggleRunExpanded(item.run.id)\">\n <div class=\"review-item-icon\">\n @if (item.priority === 'high') {\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n }\n @if (item.priority === 'medium') {\n <i class=\"fa-solid fa-circle-dot\"></i>\n }\n @if (item.priority === 'low') {\n <i class=\"fa-solid fa-clock\"></i>\n }\n </div>\n <div class=\"review-item-content\">\n <span class=\"review-item-name\">{{ item.run.testName }}</span>\n <span class=\"review-item-reason\">{{ item.reason }}</span>\n </div>\n <div class=\"review-item-action\">\n <i class=\"fa-solid fa-chevron-right\"></i>\n </div>\n </div>\n }\n @if (needsReviewItems.length > 5) {\n <div class=\"review-more\">\n <button mjButton variant=\"flat\" (click)=\"changeTab('runs')\">\n View all {{ needsReviewItems.length }} items\n </button>\n </div>\n }\n </div>\n </div>\n }\n <!-- Progress Ring (when running) -->\n @if (record.Status === 'Running' || record.Status === 'Pending') {\n <div class=\"progress-section\">\n <div class=\"progress-info\">\n <i class=\"fas fa-circle-notch fa-spin\"></i>\n <span>Suite execution in progress...</span>\n </div>\n <div class=\"auto-refresh-notice\">\n <i class=\"fas fa-sync\"></i>\n Auto-refreshing every 5 seconds\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Test Runs Tab -->\n @if (activeTab === 'runs') {\n <div class=\"runs-tab\">\n <!-- Toolbar -->\n @if (testRunsLoaded && testRuns.length > 0) {\n <div class=\"runs-toolbar\">\n <div class=\"run-filters\">\n <button class=\"filter-btn\"\n [class.active]=\"runStatusFilter === null\"\n (click)=\"setRunStatusFilter(null)\">\n All ({{ testRuns.length }})\n </button>\n @if (getRunCountByStatus('Passed') > 0) {\n <button class=\"filter-btn passed\"\n [class.active]=\"runStatusFilter === 'Passed'\"\n (click)=\"setRunStatusFilter('Passed')\"\n >\n <i class=\"fas fa-check\"></i> Passed ({{ getRunCountByStatus('Passed') }})\n </button>\n }\n @if (getRunCountByStatus('Failed') > 0) {\n <button class=\"filter-btn failed\"\n [class.active]=\"runStatusFilter === 'Failed'\"\n (click)=\"setRunStatusFilter('Failed')\"\n >\n <i class=\"fas fa-times\"></i> Failed ({{ getRunCountByStatus('Failed') }})\n </button>\n }\n @if (getRunCountByStatus('Error') > 0) {\n <button class=\"filter-btn error\"\n [class.active]=\"runStatusFilter === 'Error'\"\n (click)=\"setRunStatusFilter('Error')\"\n >\n <i class=\"fas fa-exclamation\"></i> Error ({{ getRunCountByStatus('Error') }})\n </button>\n }\n </div>\n <div class=\"runs-actions\">\n <button mjButton (click)=\"exportToCSV()\">\n <i class=\"fas fa-download\"></i> Export CSV\n </button>\n </div>\n </div>\n }\n <!-- Loading State -->\n @if (loadingTestRuns) {\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 <!-- Test Runs List -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"test-runs-list\">\n @for (run of getFilteredTestRuns(); track run) {\n <div class=\"test-run-card\">\n <div class=\"test-run-item\" (click)=\"toggleRunExpanded(run.ID)\">\n <div class=\"run-sequence\">{{ run.Sequence || '-' }}</div>\n <div class=\"run-icon\" [style.background-color]=\"getRunStatusColor(run.Status)\">\n <i class=\"fas\" [ngClass]=\"getRunStatusIcon(run.Status)\"></i>\n </div>\n <div class=\"run-content\">\n <div class=\"run-header-row\">\n <div class=\"run-name\">{{ run.Test }}</div>\n <!-- Evaluation Badge -->\n <app-evaluation-badge\n [executionStatus]=\"run.Status\"\n [originalStatus]=\"run.Status\"\n [autoScore]=\"run.Score\"\n [humanRating]=\"getFeedbackRating(run.ID) || null\"\n [humanIsCorrect]=\"getHumanIsCorrect(run.ID)\"\n [hasHumanFeedback]=\"hasFeedback(run.ID)\"\n [preferences]=\"evalPreferences\"\n [mode]=\"'compact'\">\n </app-evaluation-badge>\n </div>\n <div class=\"run-meta\">\n @if (run.DurationSeconds) {\n <span class=\"run-duration\">\n <i class=\"fas fa-clock\"></i> {{ run.DurationSeconds.toFixed(1) }}s\n </span>\n }\n @if (run.CostUSD) {\n <span class=\"run-cost\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.CostUSD.toFixed(6) }}\n </span>\n }\n @if (run.TargetLogEntityID && run.TargetLogID) {\n <mj-entity-link-pill\n [entityName]=\"run.TargetLogEntity\"\n [recordId]=\"run.TargetLogID\">\n </mj-entity-link-pill>\n }\n </div>\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 <div class=\"run-expand\">\n <i class=\"fas\" [class.fa-chevron-down]=\"expandedRunId !== run.ID\" [class.fa-chevron-up]=\"expandedRunId === run.ID\"></i>\n </div>\n </div>\n <!-- Expanded Inline Feedback -->\n @if (expandedRunId === run.ID) {\n <div class=\"inline-feedback\">\n <div class=\"feedback-divider\"></div>\n <div class=\"feedback-section\">\n <div class=\"feedback-label\">Quick Feedback</div>\n <div class=\"inline-rating\">\n <div class=\"rating-numbers\">\n @for (num of [1,2,3,4,5,6,7,8,9,10]; track num) {\n <button\n type=\"button\"\n class=\"rating-btn\"\n [class.selected]=\"num === inlineRating\"\n [class.hover]=\"num === inlineHoverRating\"\n [class.low]=\"num <= 3\"\n [class.mid]=\"num >= 4 && num <= 6\"\n [class.high]=\"num >= 7\"\n (click)=\"setInlineRating(num); $event.stopPropagation()\"\n (mouseenter)=\"inlineHoverRating = num\"\n (mouseleave)=\"inlineHoverRating = 0\">\n {{ num }}\n </button>\n }\n </div>\n @if (inlineRating > 0) {\n <div class=\"rating-info\">\n <span class=\"rating-value\">{{ inlineRating }}/10</span>\n <span class=\"rating-label-text\">{{ getInlineRatingLabel() }}</span>\n </div>\n }\n </div>\n <div class=\"correctness-row\">\n <span class=\"correctness-label\">Was it correct?</span>\n <div class=\"correctness-options\">\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"true\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Yes</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"false\" [(ngModel)]=\"inlineIsCorrect\">\n <span>No</span>\n </label>\n <label class=\"radio-opt\" (click)=\"$event.stopPropagation()\">\n <input type=\"radio\" name=\"correct-{{run.ID}}\" [value]=\"null\" [(ngModel)]=\"inlineIsCorrect\">\n <span>Not Sure</span>\n </label>\n </div>\n </div>\n <div class=\"comments-row\" (click)=\"$event.stopPropagation()\">\n <textarea\n class=\"feedback-textarea\"\n [(ngModel)]=\"inlineComments\"\n placeholder=\"Add comments or corrections...\"\n rows=\"3\"></textarea>\n </div>\n <div class=\"feedback-actions\" (click)=\"$event.stopPropagation()\">\n <button mjButton (click)=\"openTestRun(run.ID)\">\n <i class=\"fas fa-external-link-alt\"></i> View Full Details\n </button>\n <button mjButton\n variant=\"primary\"\n (click)=\"saveInlineFeedback()\"\n [disabled]=\"!canSubmitInlineFeedback() || savingInlineFeedback\">\n <i class=\"fas\" [ngClass]=\"savingInlineFeedback ? 'fa-spinner fa-spin' : 'fa-save'\"></i>\n {{ savingInlineFeedback ? 'Saving...' : (hasFeedback(run.ID) ? 'Update' : 'Save') }}\n </button>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (testRunsLoaded && !loadingTestRuns && testRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-inbox\"\n Title=\"No Test Runs Found\"\n Message=\"No test runs have been recorded for this suite execution.\" />\n }\n <!-- Filtered Empty -->\n @if (testRunsLoaded && !loadingTestRuns && testRuns.length > 0 && getFilteredTestRuns().length === 0) {\n <mj-empty-state\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter\"\n Title=\"No Matching Runs\"\n Message=\"No test runs match the current filter.\"\n ActionText=\"Clear Filter\"\n ActionVariant=\"outline\"\n (Action)=\"setRunStatusFilter(null)\" />\n }\n </div>\n }\n\n <!-- Details Tab -->\n @if (activeTab === 'details') {\n <div class=\"details-tab\">\n <div class=\"details-card\">\n <h3><i class=\"fas fa-info-circle\"></i> Run Information</h3>\n <div class=\"details-grid\">\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test Suite</div>\n <div class=\"detail-value\">\n @if (testSuite) {\n <a href=\"javascript:void(0)\" (click)=\"openTestSuite()\">{{ testSuite.Name }}</a>\n }\n @if (!testSuite) {\n <span>Loading...</span>\n }\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Status</div>\n <div class=\"detail-value\">\n <span class=\"status-inline\" [ngClass]=\"getStatusClass()\">{{ record.Status }}</span>\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Run By</div>\n <div class=\"detail-value\">{{ record.RunByUser || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Environment</div>\n <div class=\"detail-value\">{{ record.Environment || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Trigger Type</div>\n <div class=\"detail-value\">{{ record.TriggerType || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Git Commit</div>\n <div class=\"detail-value monospace\">{{ record.GitCommit || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Agent Version</div>\n <div class=\"detail-value\">{{ record.AgentVersion || 'N/A' }}</div>\n </div>\n </div>\n </div>\n </div>\n }\n\n <!-- Analytics Tab -->\n @if (activeTab === 'analytics') {\n <div class=\"analytics-tab\">\n <!-- Loading State -->\n @if (loadingTestRuns) {\n <div class=\"analytics-loading\">\n <i class=\"fas fa-spinner fa-spin\"></i>\n <span>Loading test results...</span>\n </div>\n }\n <!-- Summary Statistics - Moved to top for better overview -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"analytics-section\">\n <h3><i class=\"fas fa-chart-pie\"></i> Summary Statistics</h3>\n <div class=\"stats-grid\">\n <div class=\"stat-card\">\n <div class=\"stat-icon passed\"><i class=\"fas fa-check-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getPassedCount() }}</div>\n <div class=\"stat-label\">Passed</div>\n <div class=\"stat-percent\">{{ getPassedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon failed\"><i class=\"fas fa-times-circle\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getFailedCount() }}</div>\n <div class=\"stat-label\">Failed</div>\n <div class=\"stat-percent\">{{ getFailedPercent().toFixed(1) }}%</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon score\"><i class=\"fas fa-star\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ (getAverageScore() * 100).toFixed(1) }}%</div>\n <div class=\"stat-label\">Avg Score</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon duration\"><i class=\"fas fa-clock\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ getAverageDuration().toFixed(1) }}s</div>\n <div class=\"stat-label\">Avg Duration</div>\n </div>\n </div>\n <div class=\"stat-card\">\n <div class=\"stat-icon cost\"><i class=\"fas fa-dollar-sign\"></i></div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">${{ getTotalCost().toFixed(4) }}</div>\n <div class=\"stat-label\">Total Cost</div>\n </div>\n </div>\n </div>\n </div>\n }\n <!-- Test Results Table -->\n @if (!loadingTestRuns && testRuns.length > 0) {\n <div class=\"analytics-section\">\n <div class=\"analytics-header\">\n <h3><i class=\"fas fa-table\"></i> Test Results</h3>\n <div class=\"analytics-legend\">\n <span class=\"legend-item passed\"><i class=\"fas fa-check-circle\"></i> Passed</span>\n <span class=\"legend-item failed\"><i class=\"fas fa-times-circle\"></i> Failed</span>\n <span class=\"legend-item error\"><i class=\"fas fa-exclamation-circle\"></i> Error</span>\n <span class=\"legend-item skipped\"><i class=\"fas fa-forward\"></i> Skipped</span>\n </div>\n </div>\n <!-- Results Table -->\n <div class=\"results-table-wrapper\">\n <table class=\"results-table\">\n <thead>\n <tr>\n <th class=\"seq-col\">#</th>\n <th class=\"name-col\">Test Name</th>\n @if (evalPreferences.showExecution) {\n <th class=\"status-col\">Status</th>\n }\n @if (evalPreferences.showAuto) {\n <th class=\"score-col\">Auto Score</th>\n }\n @if (evalPreferences.showHuman) {\n <th class=\"feedback-col\">Human Score</th>\n }\n <th class=\"duration-col\">Duration</th>\n <th class=\"cost-col\">Cost</th>\n </tr>\n </thead>\n <tbody>\n @for (run of testRuns; track run; let i = $index) {\n <tr\n class=\"result-row\"\n [class.row-passed]=\"run.Status === 'Passed'\"\n [class.row-failed]=\"run.Status === 'Failed'\"\n [class.row-error]=\"run.Status === 'Error'\"\n [class.row-skipped]=\"run.Status === 'Skipped'\"\n (click)=\"openTestRun(run.ID)\">\n <td class=\"seq-col\">{{ i + 1 }}</td>\n <td class=\"name-col\">\n <div class=\"test-name-wrapper\">\n <span class=\"test-name\">{{ run.Test || 'Unknown Test' }}</span>\n @if (getRunTags(run).length > 0) {\n <div class=\"test-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 </td>\n @if (evalPreferences.showExecution) {\n <td class=\"status-col\">\n <span class=\"status-badge\" [ngClass]=\"'status-' + run.Status.toLowerCase()\">\n <i class=\"fas\"\n [class.fa-check-circle]=\"run.Status === 'Passed'\"\n [class.fa-times-circle]=\"run.Status === 'Failed'\"\n [class.fa-exclamation-circle]=\"run.Status === 'Error'\"\n [class.fa-forward]=\"run.Status === 'Skipped'\"\n [class.fa-clock]=\"run.Status === 'Pending'\"\n [class.fa-spinner]=\"run.Status === 'Running'\"\n [class.fa-spin]=\"run.Status === 'Running'\"></i>\n {{ run.Status }}\n </span>\n </td>\n }\n @if (evalPreferences.showAuto) {\n <td class=\"score-col\">\n @if (run.Score != null) {\n <div class=\"score-display\">\n <div class=\"score-bar-mini\">\n <div class=\"score-fill\"\n [style.width.%]=\"run.Score * 100\"\n [class.high]=\"run.Score >= 0.8\"\n [class.medium]=\"run.Score >= 0.5 && run.Score < 0.8\"\n [class.low]=\"run.Score < 0.5\"></div>\n </div>\n <span class=\"score-text\">{{ (run.Score * 100).toFixed(0) }}%</span>\n </div>\n }\n @if (run.Score == null) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n }\n @if (evalPreferences.showHuman) {\n <td class=\"feedback-col\">\n @if (hasFeedback(run.ID)) {\n <div class=\"feedback-display\">\n <span class=\"feedback-rating\" [class.low]=\"getFeedbackRating(run.ID) <= 3\" [class.mid]=\"getFeedbackRating(run.ID) >= 4 && getFeedbackRating(run.ID) <= 6\" [class.high]=\"getFeedbackRating(run.ID) >= 7\">\n {{ getFeedbackRating(run.ID) }}/10\n </span>\n @if (getHumanIsCorrect(run.ID) !== null) {\n <span class=\"feedback-correctness\">\n <i class=\"fas\" [class.fa-check]=\"getHumanIsCorrect(run.ID) === true\" [class.fa-times]=\"getHumanIsCorrect(run.ID) === false\" [class.correct]=\"getHumanIsCorrect(run.ID) === true\" [class.incorrect]=\"getHumanIsCorrect(run.ID) === false\"></i>\n </span>\n }\n </div>\n }\n @if (!hasFeedback(run.ID)) {\n <span class=\"na-value needs-review\">\n <i class=\"fas fa-user-clock\"></i>\n </span>\n }\n </td>\n }\n <td class=\"duration-col\">\n @if (run.DurationSeconds) {\n <span>{{ run.DurationSeconds.toFixed(1) }}s</span>\n }\n @if (!run.DurationSeconds) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n <td class=\"cost-col\">\n @if (run.CostUSD) {\n <span>${{ run.CostUSD.toFixed(4) }}</span>\n }\n @if (!run.CostUSD) {\n <span class=\"na-value\">\u2014</span>\n }\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n </div>\n }\n <!-- Empty State -->\n @if (!loadingTestRuns && testRunsLoaded && testRuns.length === 0) {\n <mj-empty-state\n Icon=\"fa-solid fa-chart-bar\"\n Title=\"No Test Results Yet\"\n Message=\"Test runs will appear here once the suite execution completes.\" />\n }\n </div>\n }\n\n <!-- Execution Tab -->\n @if (activeTab === 'execution') {\n <div class=\"execution-tab\">\n <mj-execution-context\n [machineName]=\"record.MachineName\"\n [machineId]=\"record.MachineID\"\n [runByUserName]=\"record.RunByUserName\"\n [runByUserEmail]=\"record.RunByUserEmail\"\n [runContextDetailsJson]=\"record.RunContextDetails\">\n </mj-execution-context>\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>Re-run Suite</span>\n <span class=\"shortcut-keys\"><kbd>Cmd</kbd><kbd>Shift</kbd><kbd>R</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</div>\n", styles: ["/* ===================================\n Test Suite Run Form - Premium UX\n World-class responsive design\n =================================== */\n\n/* CSS Custom Properties */\n:host {\n --suite-run-primary: var(--mj-brand-primary);\n --suite-run-primary-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-success: var(--mj-status-success);\n --suite-run-success-light: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n --suite-run-danger: var(--mj-status-error);\n --suite-run-danger-light: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n --suite-run-warning: var(--mj-status-warning);\n --suite-run-warning-light: color-mix(in srgb, var(--mj-status-warning) 10%, var(--mj-bg-surface));\n --suite-run-info: var(--mj-brand-primary);\n --suite-run-info-light: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n --suite-run-neutral: var(--mj-text-muted);\n --suite-run-neutral-light: var(--mj-bg-surface-card);\n --suite-run-bg: var(--mj-bg-surface-card);\n --suite-run-card: var(--mj-bg-surface);\n --suite-run-border: var(--mj-border-default);\n --suite-run-text: var(--mj-text-primary);\n --suite-run-text-secondary: var(--mj-text-muted);\n --suite-run-radius: 12px;\n --suite-run-shadow: var(--mj-shadow-sm);\n --suite-run-shadow-lg: var(--mj-shadow-lg);\n --suite-run-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* Base Container */\n.test-suite-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--suite-run-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n/* ===================================\n Header Section\n =================================== */\n.suite-run-header {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n padding: 20px 24px;\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(--suite-run-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(--suite-run-text-secondary);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--suite-run-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 Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n margin-bottom: 24px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n align-items: flex-start;\n}\n\n.suite-run-icon {\n width: 56px;\n height: 56px;\n border-radius: var(--suite-run-radius);\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(--suite-run-shadow);\n}\n\n.suite-run-info h1 {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.suite-run-meta {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.025em;\n}\n\n.status-badge.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-badge.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.meta-tag {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n background: var(--suite-run-neutral-light);\n border-radius: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.meta-tag i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n/* ===================================\n Metrics Bar\n =================================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.metric-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n padding: 14px;\n transition: var(--suite-run-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-card);\n border-radius: 10px;\n color: var(--suite-run-primary);\n font-size: 16px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.metric-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n margin-top: 2px;\n}\n\n/* ===================================\n Results Summary\n =================================== */\n.results-summary {\n display: flex;\n gap: 12px;\n padding-top: 20px;\n border-top: 1px solid var(--suite-run-border);\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n.result-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: 10px;\n flex-shrink: 0;\n transition: var(--suite-run-transition);\n}\n\n.result-item:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.result-icon {\n font-size: 24px;\n}\n\n.result-content {\n display: flex;\n flex-direction: column;\n}\n\n.result-count {\n font-size: 20px;\n font-weight: 700;\n line-height: 1.2;\n}\n\n.result-label {\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.result-item.passed .result-icon,\n.result-item.passed .result-count {\n color: var(--suite-run-success);\n}\n\n.result-item.failed .result-icon,\n.result-item.failed .result-count {\n color: var(--suite-run-danger);\n}\n\n.result-item.error .result-icon,\n.result-item.error .result-count {\n color: var(--suite-run-warning);\n}\n\n.result-item.skipped .result-icon,\n.result-item.skipped .result-count {\n color: var(--suite-run-neutral);\n}\n\n.result-item.total .result-icon,\n.result-item.total .result-count {\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Tabs\n =================================== */\n.tabs-container {\n background: var(--suite-run-card);\n border-bottom: 1px solid var(--suite-run-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 24px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--suite-run-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tab.active {\n color: var(--suite-run-primary);\n border-bottom-color: var(--suite-run-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--suite-run-border);\n color: var(--suite-run-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: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.tab-shortcut {\n display: none;\n width: 18px;\n height: 18px;\n background: var(--suite-run-neutral-light);\n border-radius: 4px;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n align-items: center;\n justify-content: center;\n margin-left: 4px;\n}\n\n/* ===================================\n Tab Content\n =================================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* ===================================\n Overview Tab\n =================================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n max-width: 800px;\n margin: 0 auto;\n width: 100%;\n}\n\n.result-hero {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 48px 32px;\n text-align: center;\n border: 2px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n}\n\n.result-hero.passed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-success);\n}\n\n.result-hero.failed {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-danger);\n}\n\n.result-hero.running {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-primary);\n}\n\n.result-hero.pending {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: var(--suite-run-info);\n}\n\n.result-hero-icon {\n font-size: 72px;\n margin-bottom: 20px;\n}\n\n.result-hero.passed .result-hero-icon {\n color: var(--suite-run-success);\n}\n\n.result-hero.failed .result-hero-icon {\n color: var(--suite-run-danger);\n}\n\n.result-hero.running .result-hero-icon {\n color: var(--suite-run-primary);\n}\n\n.result-hero.pending .result-hero-icon {\n color: var(--suite-run-info);\n}\n\n.result-hero-text h2 {\n margin: 0 0 16px 0;\n font-size: 32px;\n font-weight: 800;\n color: var(--suite-run-text);\n letter-spacing: -0.025em;\n}\n\n.result-hero-stats {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 32px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-divider {\n width: 1px;\n height: 40px;\n background: var(--suite-run-border);\n}\n\n/* Progress Section */\n.progress-section {\n background: var(--suite-run-primary-light);\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n border-radius: var(--suite-run-radius);\n padding: 20px;\n text-align: center;\n}\n\n.progress-info {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 500;\n color: var(--suite-run-primary);\n margin-bottom: 8px;\n}\n\n.progress-info i {\n font-size: 20px;\n}\n\n.auto-refresh-notice {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* ===================================\n Test Runs Tab\n =================================== */\n.runs-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n/* Loading Skeleton */\n.loading-state {\n animation: fadeIn 0.3s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\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: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n border: 1px solid var(--suite-run-border);\n}\n\n.skeleton-sequence {\n width: 32px;\n height: 32px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 50%;\n}\n\n.skeleton-icon {\n width: 40px;\n height: 40px;\n background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 8px;\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 background: linear-gradient(90deg, var(--mj-bg-surface-sunken) 25%, var(--mj-border-default) 50%, var(--mj-bg-surface-sunken) 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 4px;\n}\n\n.skeleton-line.wide {\n width: 70%;\n}\n\n.skeleton-line.narrow {\n width: 40%;\n}\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* Test Runs List */\n.test-runs-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n transform: translateX(4px);\n}\n\n.test-run-item:active {\n transform: translateX(2px);\n}\n\n.run-sequence {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 13px;\n font-weight: 700;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 10px;\n color: var(--mj-text-inverse);\n font-size: 16px;\n flex-shrink: 0;\n box-shadow: var(--suite-run-shadow);\n}\n\n.run-content {\n flex: 1;\n min-width: 0;\n}\n\n.run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.run-meta {\n display: flex;\n gap: 16px;\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n flex-wrap: wrap;\n}\n\n.run-status {\n font-weight: 700;\n}\n\n.run-score,\n.run-duration {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-score i,\n.run-duration i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n.test-run-item > i {\n color: var(--mj-border-strong);\n font-size: 14px;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover > i {\n color: var(--suite-run-primary);\n transform: translateX(4px);\n}\n\n/* ===================================\n Details Tab\n =================================== */\n.details-tab {\n max-width: 900px;\n margin: 0 auto;\n width: 100%;\n}\n\n.details-card {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.details-card h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.details-card h3 i {\n color: var(--suite-run-primary);\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--suite-run-text);\n word-wrap: break-word;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n font-size: 12px;\n background: var(--suite-run-neutral-light);\n padding: 6px 10px;\n border-radius: 6px;\n}\n\n.detail-value a {\n color: var(--suite-run-primary);\n text-decoration: none;\n font-weight: 500;\n transition: var(--suite-run-transition);\n}\n\n.detail-value a:hover {\n color: var(--mj-brand-primary-hover);\n text-decoration: underline;\n}\n\n.status-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-inline.status-completed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.status-inline.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.status-inline.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.status-inline.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.status-inline.status-cancelled {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n/* ===================================\n Keyboard Shortcuts\n =================================== */\n/* 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(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n box-shadow: var(--suite-run-shadow);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n z-index: 99;\n transition: var(--suite-run-transition);\n opacity: 0.7;\n}\n\n.shortcuts-toggle:hover {\n opacity: 1;\n transform: scale(1.1);\n color: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n}\n\n.keyboard-shortcuts {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n padding: 12px 16px;\n box-shadow: var(--suite-run-shadow-lg);\n font-size: 12px;\n z-index: 100;\n opacity: 0.9;\n transition: var(--suite-run-transition);\n}\n\n.keyboard-shortcuts:hover {\n opacity: 1;\n}\n\n.shortcuts-header {\n display: flex;\n align-items: center;\n gap: 6px;\n font-weight: 600;\n color: var(--suite-run-text);\n margin-bottom: 10px;\n padding-bottom: 8px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.shortcuts-header i {\n color: var(--suite-run-primary);\n}\n\n.shortcuts-close {\n margin-left: auto;\n background: none;\n border: none;\n cursor: pointer;\n color: var(--suite-run-text-muted);\n font-size: 12px;\n padding: 2px 4px;\n border-radius: 4px;\n transition: var(--suite-run-transition);\n}\n\n.shortcuts-close:hover {\n color: var(--suite-run-text);\n background: var(--suite-run-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 gap: 16px;\n}\n\n.shortcut-item span:first-child {\n color: var(--suite-run-text-secondary);\n}\n\n.shortcut-keys {\n display: flex;\n gap: 4px;\n}\n\nkbd {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-strong);\n border-radius: 4px;\n font-family: inherit;\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text);\n box-shadow: 0 1px 0 var(--mj-text-disabled);\n}\n\n/* ===================================\n Responsive Design - Tablet\n =================================== */\n@media (max-width: 1024px) {\n .suite-run-header {\n padding: 16px 20px;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .result-hero-stats {\n flex-direction: column;\n gap: 16px;\n }\n\n .stat-divider {\n display: none;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .tab-shortcut {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Mobile\n =================================== */\n@media (max-width: 768px) {\n .suite-run-header {\n padding: 16px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .suite-run-icon {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .suite-run-info h1 {\n font-size: 20px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 8px;\n }\n\n .metric-card {\n padding: 12px;\n flex-direction: column;\n text-align: center;\n gap: 8px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n }\n\n .metric-value {\n font-size: 16px;\n }\n\n .results-summary {\n gap: 8px;\n padding-top: 16px;\n flex-wrap: nowrap;\n overflow-x: auto;\n padding-bottom: 8px;\n margin-bottom: -8px;\n }\n\n .result-item {\n padding: 10px 12px;\n min-width: 90px;\n }\n\n .result-icon {\n font-size: 20px;\n }\n\n .result-count {\n font-size: 18px;\n }\n\n .tabs {\n padding: 0 16px;\n }\n\n .tab {\n padding: 14px 16px;\n font-size: 13px;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 32px 20px;\n }\n\n .result-hero-icon {\n font-size: 56px;\n }\n\n .result-hero-text h2 {\n font-size: 24px;\n }\n\n .stat-value {\n font-size: 20px;\n }\n\n .test-run-item {\n padding: 14px;\n }\n\n .run-sequence {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n\n .run-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .run-name {\n font-size: 13px;\n }\n\n .run-meta {\n gap: 10px;\n font-size: 11px;\n }\n\n .details-card {\n padding: 16px;\n }\n\n .details-grid {\n gap: 16px;\n }\n\n .keyboard-shortcuts, .shortcuts-toggle {\n display: none;\n }\n}\n\n/* ===================================\n Responsive Design - Small Mobile\n =================================== */\n@media (max-width: 480px) {\n .suite-run-header {\n padding: 12px;\n }\n\n .breadcrumb {\n font-size: 12px;\n margin-bottom: 12px;\n }\n\n .suite-run-icon {\n width: 44px;\n height: 44px;\n font-size: 18px;\n }\n\n .suite-run-info h1 {\n font-size: 18px;\n }\n\n .suite-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .meta-tag {\n font-size: 11px;\n padding: 3px 8px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n gap: 6px;\n }\n\n .metric-icon {\n width: 32px;\n height: 32px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .result-item {\n padding: 8px 10px;\n min-width: 80px;\n gap: 8px;\n }\n\n .result-icon {\n font-size: 18px;\n }\n\n .result-count {\n font-size: 16px;\n }\n\n .result-label {\n font-size: 9px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 24px 16px;\n }\n\n .result-hero-icon {\n font-size: 48px;\n margin-bottom: 16px;\n }\n\n .result-hero-text h2 {\n font-size: 20px;\n margin-bottom: 12px;\n }\n\n .stat-value {\n font-size: 18px;\n }\n\n .stat-label {\n font-size: 10px;\n }\n\n .progress-section {\n padding: 16px;\n }\n\n .progress-info {\n font-size: 14px;\n }\n\n .test-run-item {\n padding: 12px;\n gap: 10px;\n }\n\n .run-sequence {\n width: 24px;\n height: 24px;\n font-size: 11px;\n }\n\n .run-icon {\n width: 32px;\n height: 32px;\n font-size: 12px;\n border-radius: 8px;\n }\n\n .run-name {\n font-size: 12px;\n margin-bottom: 3px;\n }\n\n .run-meta {\n gap: 8px;\n font-size: 10px;\n }\n\n .details-card {\n padding: 14px;\n }\n\n .details-card h3 {\n font-size: 14px;\n margin-bottom: 16px;\n }\n\n .detail-label {\n font-size: 10px;\n }\n\n .detail-value {\n font-size: 13px;\n }\n}\n\n/* ===================================\n Touch Device Optimizations\n =================================== */\n@media (hover: none) and (pointer: coarse) {\n .test-run-item {\n min-height: 64px;\n }\n\n .test-run-item:hover {\n transform: none;\n background: var(--suite-run-card);\n border-color: var(--suite-run-border);\n }\n\n .test-run-item:active {\n background: var(--suite-run-primary-light);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n }\n\n .tab:hover {\n background: transparent;\n color: var(--suite-run-text-secondary);\n }\n\n .tab:active {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n }\n\n .metric-card:hover {\n transform: none;\n box-shadow: none;\n }\n\n .result-item:hover {\n transform: none;\n box-shadow: none;\n }\n\n .keyboard-shortcuts {\n display: none;\n }\n}\n\n/* ===================================\n Print Styles\n =================================== */\n@media print {\n .suite-run-header {\n background: var(--mj-bg-surface);\n box-shadow: none;\n border-bottom: 2px solid var(--mj-text-primary);\n }\n\n .tabs-container,\n .header-actions,\n .keyboard-shortcuts {\n display: none;\n }\n\n .tab-content {\n padding: 20px 0;\n }\n\n .result-hero,\n .test-run-item,\n .details-card {\n box-shadow: none;\n border: 1px solid var(--mj-border-strong);\n }\n}\n\n/* ===================================\n Dark Mode Support (Future)\n =================================== */\n@media (prefers-color-scheme: dark) {\n /* Ready for dark mode implementation */\n}\n\n/* ===================================\n Tags Bar - Sleek Inline Display\n =================================== */\n.tags-bar {\n margin-top: 16px;\n padding: 8px 14px;\n background: color-mix(in srgb, var(--mj-brand-primary) 6%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label {\n color: var(--suite-run-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label i {\n opacity: 0.6;\n}\n\n.tags-bar-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--suite-run-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n background: var(--suite-run-primary-light);\n}\n\n.tags-bar-edit i {\n font-size: 10px;\n}\n\n/* ===================================\n Tags Editor Panel - Expanded Edit Mode\n =================================== */\n.tags-editor-panel {\n margin-top: 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n border-radius: 10px;\n overflow: hidden;\n box-shadow: var(--mj-shadow-md);\n max-width: 600px;\n}\n\n.tags-editor-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: var(--suite-run-primary-light);\n border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-primary);\n color: var(--suite-run-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--suite-run-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--suite-run-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--suite-run-neutral-light);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n background: var(--suite-run-card);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.tag-text-input::placeholder {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* ===================================\n Runs Toolbar\n =================================== */\n.runs-toolbar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n padding: 12px 16px;\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n flex-wrap: wrap;\n gap: 12px;\n}\n\n.run-filters {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.filter-btn {\n padding: 6px 14px;\n border: 1px solid var(--suite-run-border);\n background: var(--suite-run-card);\n border-radius: 20px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n cursor: pointer;\n transition: var(--suite-run-transition);\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.filter-btn:hover {\n border-color: var(--suite-run-primary);\n color: var(--suite-run-primary);\n}\n\n.filter-btn.active {\n background: var(--suite-run-primary);\n border-color: var(--suite-run-primary);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.passed:hover,\n.filter-btn.passed.active {\n background: var(--suite-run-success);\n border-color: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.failed:hover,\n.filter-btn.failed.active {\n background: var(--suite-run-danger);\n border-color: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.filter-btn.error:hover,\n.filter-btn.error.active {\n background: var(--suite-run-warning);\n border-color: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.runs-actions {\n display: flex;\n gap: 8px;\n}\n\n/* ===================================\n Test Run Card (Expandable)\n =================================== */\n.test-run-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n margin-bottom: 10px;\n}\n\n.test-run-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.test-run-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.run-header-row {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 4px;\n}\n\n.run-feedback-indicator {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 2px 8px;\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.run-feedback-indicator i {\n font-size: 10px;\n}\n\n.run-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n margin-top: 6px;\n}\n\n.tag-mini {\n display: inline-flex;\n padding: 2px 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n border-radius: 10px;\n font-size: 10px;\n font-weight: 500;\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) 10%, 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.run-expand {\n color: var(--suite-run-text-secondary);\n transition: var(--suite-run-transition);\n}\n\n.test-run-item:hover .run-expand {\n color: var(--suite-run-primary);\n}\n\n.run-cost {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.run-cost i {\n font-size: 10px;\n opacity: 0.7;\n}\n\n/* ===================================\n Inline Feedback\n =================================== */\n.inline-feedback {\n padding: 0 16px 16px;\n animation: slideDown 0.2s ease-out;\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.feedback-divider {\n height: 1px;\n background: var(--suite-run-border);\n margin-bottom: 16px;\n}\n\n.feedback-section {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-label {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.inline-rating {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.rating-numbers {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n}\n\n.rating-btn {\n width: 36px;\n height: 36px;\n border: 2px solid var(--suite-run-border);\n border-radius: 8px;\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-text-secondary);\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.rating-btn:hover,\n.rating-btn.hover {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.low:hover,\n.rating-btn.low.hover {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.rating-btn.mid:hover,\n.rating-btn.mid.hover {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.rating-btn.high:hover,\n.rating-btn.high.hover {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.rating-btn.selected {\n transform: scale(1.1);\n box-shadow: var(--mj-shadow-md);\n}\n\n.rating-btn.selected.low {\n border-color: var(--suite-run-danger);\n background: var(--suite-run-danger);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.mid {\n border-color: var(--suite-run-warning);\n background: var(--suite-run-warning);\n color: var(--mj-text-inverse);\n}\n\n.rating-btn.selected.high {\n border-color: var(--suite-run-success);\n background: var(--suite-run-success);\n color: var(--mj-text-inverse);\n}\n\n.rating-info {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 14px;\n background: var(--suite-run-neutral-light);\n border-radius: 8px;\n}\n\n.rating-value {\n font-size: 18px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.rating-label-text {\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.correctness-row {\n display: flex;\n align-items: center;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.correctness-label {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.correctness-options {\n display: flex;\n gap: 16px;\n}\n\n.radio-opt {\n display: flex;\n align-items: center;\n gap: 6px;\n cursor: pointer;\n font-size: 13px;\n color: var(--suite-run-text-secondary);\n}\n\n.radio-opt input[type=\"radio\"] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n\n.comments-row {\n width: 100%;\n}\n\n.feedback-textarea {\n width: 100%;\n padding: 12px;\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n font-size: 14px;\n font-family: inherit;\n resize: vertical;\n min-height: 80px;\n}\n\n.feedback-textarea:focus {\n outline: none;\n border-color: var(--suite-run-primary);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.feedback-actions {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n padding-top: 8px;\n}\n\n/* ===================================\n Mobile Responsive Updates\n =================================== */\n@media (max-width: 768px) {\n .tags-bar {\n padding: 8px 12px;\n }\n\n .tags-bar-content {\n gap: 8px;\n }\n\n .tag-inline {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel {\n margin-top: 12px;\n }\n\n .tags-editor-body {\n padding: 12px;\n }\n\n .tags-editor-footer {\n padding: 10px 12px;\n }\n\n .runs-toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .run-filters {\n justify-content: center;\n }\n\n .runs-actions {\n justify-content: center;\n }\n\n .rating-numbers {\n justify-content: center;\n }\n\n .rating-btn {\n width: 32px;\n height: 32px;\n font-size: 12px;\n }\n\n .correctness-row {\n flex-direction: column;\n align-items: flex-start;\n gap: 8px;\n }\n\n .feedback-actions {\n flex-direction: column;\n }\n\n .feedback-actions button {\n width: 100%;\n }\n}\n\n/* ===================================\n Animations\n =================================== */\n@keyframes pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n}\n\n.result-hero.running .result-hero-icon {\n animation: pulse 2s ease-in-out infinite;\n}\n\n/* Tab content fade in */\n.overview-tab,\n.runs-tab,\n.details-tab,\n.analytics-tab {\n animation: fadeIn 0.3s ease;\n}\n\n/* ===================================\n Analytics Tab\n =================================== */\n.analytics-tab {\n max-width: 1200px;\n margin: 0 auto;\n width: 100%;\n display: flex;\n flex-direction: column;\n gap: 24px;\n}\n\n.analytics-section {\n background: var(--suite-run-card);\n border-radius: var(--suite-run-radius);\n padding: 24px;\n box-shadow: var(--suite-run-shadow);\n}\n\n.analytics-section h3 {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 20px 0;\n font-size: 16px;\n font-weight: 600;\n color: var(--suite-run-text);\n padding-bottom: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-section h3 i {\n color: var(--suite-run-primary);\n}\n\n.analytics-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: 12px;\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.analytics-header h3 {\n margin: 0;\n padding: 0;\n border: none;\n}\n\n.analytics-legend {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n}\n\n.legend-item {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.legend-item.passed {\n color: var(--suite-run-success);\n}\n\n.legend-item.failed {\n color: var(--suite-run-danger);\n}\n\n.legend-item.error {\n color: var(--suite-run-warning);\n}\n\n.legend-item.skipped {\n color: var(--suite-run-neutral);\n}\n\n/* Performance Matrix */\n.performance-matrix {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.matrix-row {\n display: grid;\n grid-template-columns: 2fr 120px 150px 100px 100px;\n border-bottom: 1px solid var(--suite-run-border);\n transition: var(--suite-run-transition);\n cursor: pointer;\n}\n\n.matrix-row:last-child {\n border-bottom: none;\n}\n\n.matrix-row:hover:not(.matrix-header-row) {\n background: var(--suite-run-primary-light);\n}\n\n.matrix-row.passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.matrix-row.failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.matrix-row.error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.matrix-row.skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n.matrix-header-row {\n background: var(--suite-run-neutral-light);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n cursor: default;\n}\n\n.matrix-cell {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n}\n\n.test-name-cell {\n gap: 12px;\n}\n\n.test-sequence {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--suite-run-neutral-light);\n border-radius: 50%;\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n flex-shrink: 0;\n}\n\n.test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.status-indicator {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-indicator.status-passed {\n color: var(--suite-run-success);\n}\n\n.status-indicator.status-failed {\n color: var(--suite-run-danger);\n}\n\n.status-indicator.status-error {\n color: var(--suite-run-warning);\n}\n\n.status-indicator.status-skipped {\n color: var(--suite-run-neutral);\n}\n\n.status-indicator.status-pending {\n color: var(--suite-run-info);\n}\n\n.status-indicator.status-running {\n color: var(--suite-run-primary);\n}\n\n.score-bar {\n position: relative;\n width: 100%;\n height: 20px;\n background: var(--suite-run-neutral-light);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.score-fill {\n height: 100%;\n border-radius: 10px;\n transition: width 0.3s ease;\n}\n\n.score-fill.high {\n background: var(--suite-run-success);\n}\n\n.score-fill.medium {\n background: var(--suite-run-warning);\n}\n\n.score-fill.low {\n background: var(--suite-run-danger);\n}\n\n.score-text {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n font-size: 11px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.na-value {\n color: var(--suite-run-text-secondary);\n opacity: 0.6;\n}\n\n/* Summary Statistics Grid */\n.stats-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: 16px;\n}\n\n.stat-card {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--suite-run-border);\n border-radius: 12px;\n transition: var(--suite-run-transition);\n}\n\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--suite-run-shadow);\n}\n\n.stat-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 12px;\n font-size: 20px;\n}\n\n.stat-icon.passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.stat-icon.failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.stat-icon.score {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.stat-icon.duration {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n.stat-icon.cost {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.stat-content {\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.stat-card .stat-value {\n font-size: 24px;\n font-weight: 700;\n color: var(--suite-run-text);\n}\n\n.stat-card .stat-label {\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-percent {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n/* Responsive Analytics */\n@media (max-width: 768px) {\n .analytics-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .matrix-row {\n grid-template-columns: 1fr;\n gap: 8px;\n padding: 12px;\n }\n\n .matrix-header-row {\n display: none;\n }\n\n .matrix-cell {\n padding: 4px 0;\n }\n\n .test-name-cell::before,\n .status-cell::before,\n .score-cell::before,\n .duration-cell::before,\n .cost-cell::before {\n font-size: 10px;\n font-weight: 600;\n color: var(--suite-run-text-secondary);\n text-transform: uppercase;\n margin-right: 8px;\n min-width: 80px;\n }\n\n .status-cell::before { content: 'Status:'; }\n .score-cell::before { content: 'Score:'; }\n .duration-cell::before { content: 'Duration:'; }\n .cost-cell::before { content: 'Cost:'; }\n\n .stats-grid {\n grid-template-columns: 1fr 1fr;\n }\n\n .stat-card {\n padding: 16px;\n }\n\n .stat-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .stat-card .stat-value {\n font-size: 20px;\n }\n}\n\n/* Focus States for Accessibility */\n.tab:focus-visible,\n.test-run-item:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--suite-run-primary);\n outline-offset: 2px;\n}\n\n/* ===================================\n Analytics Loading State\n =================================== */\n.analytics-loading {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 60px 20px;\n color: var(--suite-run-text-secondary);\n}\n\n.analytics-loading i {\n font-size: 32px;\n color: var(--suite-run-primary);\n}\n\n/* ===================================\n Results Table\n =================================== */\n.results-table-wrapper {\n border: 1px solid var(--suite-run-border);\n border-radius: 8px;\n overflow: hidden;\n}\n\n.results-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n}\n\n.results-table thead {\n background: var(--suite-run-neutral-light);\n}\n\n.results-table th {\n padding: 12px 16px;\n text-align: left;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--suite-run-text-secondary);\n border-bottom: 1px solid var(--suite-run-border);\n}\n\n.results-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n vertical-align: middle;\n}\n\n.results-table tbody tr:last-child td {\n border-bottom: none;\n}\n\n/* Column widths - Fixed columns fit content, name column takes remainder (max 50%) */\n.seq-col {\n width: 40px;\n min-width: 40px;\n text-align: center;\n white-space: nowrap;\n}\n\n.name-col {\n /* Take remaining space, but cap at 50% of table width */\n width: auto;\n max-width: 50%;\n}\n\n.status-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n}\n\n.score-col {\n width: 1%; /* Shrink to fit content */\n min-width: 120px; /* Score bar needs some minimum width */\n white-space: nowrap;\n}\n\n.duration-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n.cost-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: right;\n}\n\n/* Result Row */\n.result-row {\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.result-row:hover {\n background: var(--suite-run-primary-light);\n}\n\n.result-row.row-passed {\n border-left: 4px solid var(--suite-run-success);\n}\n\n.result-row.row-failed {\n border-left: 4px solid var(--suite-run-danger);\n}\n\n.result-row.row-error {\n border-left: 4px solid var(--suite-run-warning);\n}\n\n.result-row.row-skipped {\n border-left: 4px solid var(--suite-run-neutral);\n}\n\n/* Test Name Wrapper */\n.test-name-wrapper {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.test-name-wrapper .test-name {\n font-weight: 500;\n color: var(--suite-run-text);\n}\n\n.test-tags {\n display: flex;\n flex-wrap: wrap;\n gap: 4px;\n}\n\n/* Score Display */\n.score-display {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.score-bar-mini {\n flex: 1;\n height: 6px;\n background: var(--suite-run-neutral-light);\n border-radius: 3px;\n overflow: hidden;\n min-width: 60px;\n}\n\n.score-bar-mini .score-fill {\n height: 100%;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.score-bar-mini .score-fill.high {\n background: var(--suite-run-success);\n}\n\n.score-bar-mini .score-fill.medium {\n background: var(--suite-run-warning);\n}\n\n.score-bar-mini .score-fill.low {\n background: var(--suite-run-danger);\n}\n\n.score-display .score-text {\n position: static;\n transform: none;\n font-size: 12px;\n font-weight: 600;\n color: var(--suite-run-text);\n min-width: 35px;\n text-align: right;\n}\n\n/* Status Badge in Table */\n.results-table .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.results-table .status-badge.status-passed {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.results-table .status-badge.status-failed {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.results-table .status-badge.status-error {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.results-table .status-badge.status-skipped {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.results-table .status-badge.status-pending {\n background: var(--suite-run-info-light);\n color: var(--suite-run-info);\n}\n\n.results-table .status-badge.status-running {\n background: var(--suite-run-primary-light);\n color: var(--suite-run-primary);\n}\n\n/* Responsive Results Table */\n@media (max-width: 768px) {\n .results-table-wrapper {\n overflow-x: auto;\n }\n\n .results-table {\n min-width: 600px;\n }\n\n .results-table th,\n .results-table td {\n padding: 10px 12px;\n }\n\n .name-col {\n min-width: 150px;\n }\n}\n\n/* ===================================\n High Contrast Mode\n =================================== */\n@media (prefers-contrast: high) {\n .status-badge,\n .status-inline {\n border: 2px solid currentColor;\n }\n\n .test-run-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===================================\n Evaluation Summary\n =================================== */\n.evaluation-summary {\n margin-top: 20px;\n}\n\n.eval-summary-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\n gap: 16px;\n}\n\n.eval-summary-card {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n transition: var(--suite-run-transition);\n}\n\n.eval-summary-card:hover {\n box-shadow: var(--suite-run-shadow);\n}\n\n.eval-card-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 16px;\n background: var(--suite-run-neutral-light);\n border-bottom: 1px solid var(--suite-run-border);\n font-size: 13px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-card-header i {\n color: var(--suite-run-primary);\n}\n\n.eval-card-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.eval-stat-row {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 12px;\n}\n\n.eval-stat-label {\n font-size: 12px;\n color: var(--suite-run-text-secondary);\n}\n\n.eval-stat-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--suite-run-text);\n}\n\n.eval-stat-value.correct {\n color: var(--suite-run-success);\n}\n\n.eval-stat-value.incorrect {\n color: var(--suite-run-danger);\n font-weight: 500;\n font-size: 12px;\n}\n\n.eval-stat-value.error {\n color: var(--suite-run-danger);\n}\n\n.eval-stat-value.timeout {\n color: var(--suite-run-warning);\n}\n\n.eval-card-footer {\n padding: 10px 16px;\n background: var(--suite-run-warning-light);\n border-top: 1px solid color-mix(in srgb, var(--mj-status-warning) 20%, transparent);\n}\n\n.pending-badge {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n font-weight: 500;\n color: var(--suite-run-warning);\n}\n\n.pending-badge i {\n font-size: 11px;\n}\n\n/* ===================================\n Needs Review Section\n =================================== */\n.needs-review-section {\n background: var(--suite-run-card);\n border: 1px solid var(--suite-run-border);\n border-radius: var(--suite-run-radius);\n overflow: hidden;\n}\n\n.needs-review-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 14px 20px;\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n border-bottom: 1px solid color-mix(in srgb, var(--mj-status-warning) 30%, transparent);\n}\n\n.needs-review-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-status-warning);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.needs-review-header h3 i {\n font-size: 16px;\n}\n\n.review-count {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-status-warning);\n background: color-mix(in srgb, var(--mj-bg-surface) 60%, transparent);\n padding: 2px 10px;\n border-radius: 12px;\n}\n\n.needs-review-list {\n padding: 8px;\n}\n\n.review-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n border-radius: 8px;\n cursor: pointer;\n transition: var(--suite-run-transition);\n}\n\n.review-item:hover {\n background: var(--suite-run-primary-light);\n}\n\n.review-item-icon {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n font-size: 14px;\n flex-shrink: 0;\n}\n\n.review-item.high-priority .review-item-icon {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.review-item.medium-priority .review-item-icon {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.review-item:not(.high-priority):not(.medium-priority) .review-item-icon {\n background: var(--suite-run-neutral-light);\n color: var(--suite-run-neutral);\n}\n\n.review-item-content {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 2px;\n}\n\n.review-item-name {\n font-size: 13px;\n font-weight: 500;\n color: var(--suite-run-text);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.review-item-reason {\n font-size: 11px;\n color: var(--suite-run-text-secondary);\n}\n\n.review-item-action {\n color: var(--suite-run-text-secondary);\n font-size: 12px;\n}\n\n.review-item:hover .review-item-action {\n color: var(--suite-run-primary);\n}\n\n.review-more {\n display: flex;\n justify-content: center;\n padding: 8px;\n border-top: 1px solid var(--suite-run-border);\n}\n\n/* Mobile Responsive for Evaluation */\n@media (max-width: 768px) {\n .eval-summary-grid {\n grid-template-columns: 1fr;\n }\n\n .eval-card-header {\n padding: 10px 14px;\n font-size: 12px;\n }\n\n .eval-card-body {\n padding: 12px 14px;\n }\n\n .needs-review-header {\n padding: 12px 16px;\n }\n\n .needs-review-header h3 {\n font-size: 13px;\n }\n\n .review-item {\n padding: 10px 12px;\n }\n\n .review-item-icon {\n width: 28px;\n height: 28px;\n font-size: 12px;\n }\n}\n\n/* ===================================\n Feedback Column in Analytics Table\n =================================== */\n.feedback-col {\n width: 1%; /* Shrink to fit content */\n white-space: nowrap;\n text-align: center;\n}\n\n.feedback-display {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n}\n\n.feedback-rating {\n font-size: 13px;\n font-weight: 600;\n padding: 2px 6px;\n border-radius: 4px;\n background: var(--suite-run-neutral-light);\n}\n\n.feedback-rating.low {\n background: var(--suite-run-danger-light);\n color: var(--suite-run-danger);\n}\n\n.feedback-rating.mid {\n background: var(--suite-run-warning-light);\n color: var(--suite-run-warning);\n}\n\n.feedback-rating.high {\n background: var(--suite-run-success-light);\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i {\n font-size: 12px;\n}\n\n.feedback-correctness i.correct {\n color: var(--suite-run-success);\n}\n\n.feedback-correctness i.incorrect {\n color: var(--suite-run-danger);\n}\n\n.na-value.needs-review {\n color: var(--suite-run-warning);\n opacity: 0.7;\n}\n\n.na-value.needs-review i {\n font-size: 14px;\n}\n"] }]
|
|
2325
2299
|
}], null, { handleKeyboardShortcut: [{
|
|
2326
2300
|
type: HostListener,
|
|
2327
2301
|
args: ['document:keydown', ['$event']]
|