@memberjunction/ng-dashboards 5.11.0 → 5.12.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/AI/components/agents/agent-configuration.component.d.ts +34 -2
- package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-configuration.component.js +586 -223
- package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
- package/dist/AI/components/agents/agent-editor.component.js +2 -2
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
- package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
- package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
- package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
- package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
- package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
- package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
- package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
- package/dist/AI/components/charts/time-series-chart.component.js +23 -8
- package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
- package/dist/AI/components/execution-monitoring.component.js +2 -2
- package/dist/AI/components/execution-monitoring.component.js.map +1 -1
- package/dist/AI/components/models/model-management.component.js +2 -2
- package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
- package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
- package/dist/AI/components/prompts/prompt-management.component.js +3 -3
- package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
- package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
- package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
- package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
- package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
- package/dist/AI/components/system/system-configuration.component.js +2 -2
- package/dist/AI/components/widgets/kpi-card.component.js +7 -7
- package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
- package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
- package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
- package/dist/AI/index.d.ts +1 -0
- package/dist/AI/index.d.ts.map +1 -1
- package/dist/AI/index.js +2 -0
- package/dist/AI/index.js.map +1 -1
- package/dist/APIKeys/api-applications-panel.component.js +3 -3
- package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
- package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
- package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
- package/dist/APIKeys/api-key-list.component.js +3 -3
- package/dist/APIKeys/api-key-list.component.js.map +1 -1
- package/dist/APIKeys/api-keys-resource.component.js +1 -1
- package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
- package/dist/APIKeys/api-scopes-panel.component.js +2 -2
- package/dist/APIKeys/api-usage-panel.component.js +2 -2
- package/dist/Actions/components/actions-overview.component.js +2 -2
- package/dist/Actions/components/execution-monitoring.component.js +2 -2
- package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
- package/dist/Actions/components/explorer/action-card.component.js +2 -2
- package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
- package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
- package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
- package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
- package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
- package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
- package/dist/Communication/communication-dashboard.component.js +2 -2
- package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-logs-resource.component.js +3 -3
- package/dist/Communication/communication-logs-resource.component.js.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-monitor-resource.component.js +5 -5
- package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
- package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-providers-resource.component.js +3 -3
- package/dist/Communication/communication-providers-resource.component.js.map +1 -1
- package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
- package/dist/Communication/communication-runs-resource.component.js +3 -3
- package/dist/Communication/communication-runs-resource.component.js.map +1 -1
- package/dist/Communication/communication-templates-resource.component.js +2 -2
- package/dist/Communication/communication-templates-resource.component.js.map +1 -1
- package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
- package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
- package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
- package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
- package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
- package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
- package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
- package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
- package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
- package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
- package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
- package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
- package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
- package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
- package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
- package/dist/Credentials/credentials-dashboard.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
- package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
- package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
- package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
- package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
- package/dist/DataExplorer/data-explorer-dashboard.component.js +4 -4
- package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
- package/dist/Home/home-dashboard.component.js +2 -2
- package/dist/Integration/components/activity/activity.component.d.ts +1 -1
- package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
- package/dist/Integration/components/activity/activity.component.js +5 -5
- package/dist/Integration/components/activity/activity.component.js.map +1 -1
- package/dist/Integration/components/connections/connections.component.d.ts +31 -2
- package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
- package/dist/Integration/components/connections/connections.component.js +753 -412
- package/dist/Integration/components/connections/connections.component.js.map +1 -1
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
- package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
- package/dist/Integration/components/overview/overview.component.d.ts +0 -1
- package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
- package/dist/Integration/components/overview/overview.component.js +3 -6
- package/dist/Integration/components/overview/overview.component.js.map +1 -1
- package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
- package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
- package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
- package/dist/Integration/components/schedules/schedules.component.js +97 -5
- package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
- package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
- package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
- package/dist/Integration/components/widgets/integration-card.component.js +5 -1
- package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
- package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
- package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
- package/dist/Integration/integration.module.d.ts +2 -1
- package/dist/Integration/integration.module.d.ts.map +1 -1
- package/dist/Integration/integration.module.js +7 -3
- package/dist/Integration/integration.module.js.map +1 -1
- package/dist/Integration/services/integration-data.service.d.ts +27 -2
- package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
- package/dist/Integration/services/integration-data.service.js +107 -4
- package/dist/Integration/services/integration-data.service.js.map +1 -1
- package/dist/Lists/components/lists-browse-resource.component.js +2 -2
- package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-categories-resource.component.js +2 -2
- package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
- package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
- package/dist/Lists/components/lists-operations-resource.component.js +2 -2
- package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
- package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
- package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
- package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
- package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
- package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
- package/dist/MCP/mcp-dashboard.component.js +2 -2
- package/dist/MCP/mcp-filter-panel.component.js +2 -2
- package/dist/QueryBrowser/query-browser-resource.component.js +7 -7
- package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
- package/dist/Scheduling/components/index.d.ts +0 -1
- package/dist/Scheduling/components/index.d.ts.map +1 -1
- package/dist/Scheduling/components/index.js +0 -1
- package/dist/Scheduling/components/index.js.map +1 -1
- package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
- package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
- package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
- package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
- package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
- package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
- package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
- package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
- package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
- package/dist/Testing/components/testing-analytics.component.js +2 -2
- package/dist/Testing/components/testing-analytics.component.js.map +1 -1
- package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
- package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
- package/dist/Testing/components/testing-explorer.component.js +2 -2
- package/dist/Testing/components/testing-explorer.component.js.map +1 -1
- package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
- package/dist/Testing/components/testing-review.component.js +5 -5
- package/dist/Testing/components/testing-review.component.js.map +1 -1
- package/dist/Testing/components/testing-runs.component.js +2 -2
- package/dist/Testing/components/testing-runs.component.js.map +1 -1
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
- package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
- package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
- package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
- package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
- package/dist/Testing/testing-dashboard.component.js +2 -2
- package/dist/VersionHistory/components/diff-resource.component.js +2 -2
- package/dist/VersionHistory/components/graph-resource.component.js +2 -2
- package/dist/VersionHistory/components/labels-resource.component.js +3 -3
- package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
- package/dist/VersionHistory/components/restore-resource.component.js +3 -3
- package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
- package/dist/__tests__/integration-data-service.test.js +1 -0
- package/dist/__tests__/integration-data-service.test.js.map +1 -1
- package/dist/module.d.ts +52 -49
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +25 -6
- package/dist/module.js.map +1 -1
- package/dist/public-api.d.ts +1 -1
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +1 -1
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -40
- package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
- package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
- package/dist/Scheduling/components/job-slideout.component.js +0 -459
- package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
|
@@ -1424,7 +1424,7 @@ let ModelManagementComponent = class ModelManagementComponent extends BaseResour
|
|
|
1424
1424
|
} if (rf & 2) {
|
|
1425
1425
|
i0.ɵɵadvance();
|
|
1426
1426
|
i0.ɵɵconditional(ctx.isLoading ? 1 : 2);
|
|
1427
|
-
} }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.MaxValidator, i2.NgModel, i3.SplitterComponent, i3.SplitterPaneComponent, i4.LoadingComponent, i5.DatePipe, i6.HighlightSearchPipe], styles: ["\n\n\n\n\n\n\n\n.model-management-v2[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n}\n\n\n\n.dashboard-header[_ngcontent-%COMP%] {\n background: white;\n padding: 16px 24px;\n border-bottom: 1px solid #e0e6ed;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n font-size: 22px;\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n font-size: 14px;\n}\n\n.item-count[_ngcontent-%COMP%] {\n color: #6c757d;\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: #f8f9fa;\n border-radius: 20px;\n border: 1px solid #e9ecef;\n}\n\n.header-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: #f8f9fa;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #dee2e6;\n}\n\n.view-btn[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn[_ngcontent-%COMP%]:hover {\n color: #495057;\n}\n\n.view-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #6366f1;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: #f8f9fa;\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.control-btn.primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.control-btn.primary[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n\n\nkendo-splitter[_ngcontent-%COMP%] {\n flex: 1;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n margin-top: 0;\n}\n\n[_nghost-%COMP%] .k-splitter {\n border: none;\n background: transparent;\n}\n\n[_nghost-%COMP%] .k-splitbar {\n background: #e2e8f0;\n width: 6px;\n}\n\n[_nghost-%COMP%] .k-splitbar:hover {\n background: #c7d2fe;\n}\n\n[_nghost-%COMP%] .k-pane {\n overflow: hidden;\n}\n\n\n\n.filter-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n\n\n.filter-panel-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid #f1f5f9;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.filter-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n border-radius: 20px;\n border: 1px solid #c4b5fd;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: #6366f1;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n color: #7c3aed;\n font-weight: 500;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: #94a3b8;\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.filter-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n\n\n.filter-group[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #6366f1;\n width: 16px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%], \n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]:focus, \n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n\n\n.filter-input[_ngcontent-%COMP%], \n.filter-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-input[_ngcontent-%COMP%]:focus, \n.filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n}\n\n.filter-select[_ngcontent-%COMP%] {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n\n\n.rank-filter-inputs[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n align-items: center;\n margin-top: 8px;\n}\n\n.rank-input[_ngcontent-%COMP%] {\n width: 70px;\n padding: 10px 12px;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n text-align: center;\n background: white;\n transition: all 0.3s;\n box-sizing: border-box;\n -moz-appearance: textfield;\n}\n\n.rank-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);\n}\n\n.rank-input[_ngcontent-%COMP%]::placeholder {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.rank-input[_ngcontent-%COMP%]::-webkit-inner-spin-button, \n.rank-input[_ngcontent-%COMP%]::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.rank-separator[_ngcontent-%COMP%] {\n color: #64748b;\n font-size: 13px;\n font-weight: 600;\n}\n\n\n\n.filter-actions[_ngcontent-%COMP%] {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid #f1f5f9;\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n color: #64748b;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);\n border-color: #cbd5e1;\n color: #475569;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f8fafc;\n border-radius: 3px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #94a3b8;\n}\n\n\n\n.content-area[_ngcontent-%COMP%] {\n height: 100%;\n padding: 28px;\n overflow-y: auto;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\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 height: 100%;\n text-align: center;\n color: #64748b;\n padding: 60px 32px;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 80px;\n background: linear-gradient(135deg, #c7d2fe 0%, #ddd6fe 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n opacity: 1;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 32px 0;\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n}\n\n\n\n.model-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.model-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid #e2e8f0;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.model-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.model-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 20px 40px -15px rgba(99, 102, 241, 0.25);\n transform: translateY(-4px);\n border-color: #c7d2fe;\n}\n\n.model-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n.model-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 25px 50px -12px rgba(99, 102, 241, 0.3);\n border-color: #a5b4fc;\n}\n\n.model-card.expanded[_ngcontent-%COMP%]::before {\n opacity: 1;\n}\n\n.card-header[_ngcontent-%COMP%] {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s;\n}\n\n.card-header[_ngcontent-%COMP%]:hover {\n background-color: #fafbfc;\n}\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.model-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.model-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: white;\n font-size: 24px;\n}\n\n.model-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.model-name[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.model-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #64748b;\n display: flex;\n align-items: center;\n gap: 6px;\n background: #f1f5f9;\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: #6366f1;\n}\n\n.meta-item.status-active[_ngcontent-%COMP%] {\n color: #059669;\n background: #d1fae5;\n}\n\n.meta-item.status-active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #059669;\n}\n\n.meta-item.status-inactive[_ngcontent-%COMP%] {\n color: #64748b;\n background: #e2e8f0;\n}\n\n.meta-item.status-inactive[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #64748b;\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #94a3b8;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon[_ngcontent-%COMP%]:hover {\n color: #6366f1;\n background: #f1f5f9;\n}\n\n.expand-icon.rotated[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n color: #6366f1;\n}\n\n.card-body[_ngcontent-%COMP%] {\n padding: 0 24px 24px 24px;\n}\n\n.model-description[_ngcontent-%COMP%] {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: #64748b;\n}\n\n.model-description.text-muted[_ngcontent-%COMP%] {\n font-style: italic;\n color: #94a3b8;\n}\n\n\n\n.expanded-content[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid #e2e8f0;\n animation: _ngcontent-%COMP%_slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.model-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 15px;\n color: #1e293b;\n font-weight: 600;\n}\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n padding: 18px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n background: white;\n border: 2px solid #e2e8f0;\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #475569;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n transform: translateY(-1px);\n}\n\n.action-btn-primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.action-btn-primary[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n\n\n.model-list[_ngcontent-%COMP%] {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid #e2e8f0;\n overflow: hidden;\n}\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 2px solid #e2e8f0;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:hover {\n background: #e2e8f0;\n color: #6366f1;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:last-child, \n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:nth-last-child(2) {\n cursor: default;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:last-child:hover, \n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:nth-last-child(2):hover {\n background: transparent;\n color: #475569;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted[_ngcontent-%COMP%] {\n color: #6366f1;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted.desc[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.data-table[_ngcontent-%COMP%] .sort-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.data-table[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:hover .sort-icon[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n opacity: 1;\n color: #6366f1;\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 18px 20px;\n font-size: 14px;\n color: #475569;\n}\n\n.name-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n color: #1e293b;\n}\n\n.name-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n font-size: 18px;\n}\n\n\n\n.rank-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.rank-badge.rank-high[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.rank-badge.rank-medium[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.rank-badge.rank-low[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.rank-badge.rank-none[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);\n color: #475569;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-badge.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.inactive[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n\n\n@media (max-width: 768px) {\n .dashboard-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .model-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .model-stats[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .card-header[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .card-body[_ngcontent-%COMP%] {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions[_ngcontent-%COMP%] {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n\n\n\n.detail-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(15, 23, 42, 0.5);\n backdrop-filter: blur(4px);\n z-index: 1000;\n opacity: 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n to {\n opacity: 1;\n }\n}\n\n\n\n.detail-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n max-width: 90vw;\n height: 100vh;\n background: white;\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible[_ngcontent-%COMP%] {\n right: 0;\n}\n\n\n\n.detail-panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n flex-shrink: 0;\n}\n\n.detail-panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: white;\n font-size: 24px;\n}\n\n.detail-title-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.detail-subtitle[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #64748b;\n font-weight: 500;\n}\n\n.detail-panel-close[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e2e8f0;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #64748b;\n}\n\n.detail-panel-close[_ngcontent-%COMP%]:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n\n\n.detail-panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n\n\n.detail-section[_ngcontent-%COMP%] {\n margin-bottom: 28px;\n}\n\n.detail-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.feature-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n color: #4f46e5;\n}\n\n.feature-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.detail-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #475569;\n}\n\n.detail-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6366f1;\n font-size: 14px;\n}\n\n\n\n.detail-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #1e293b;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n.detail-value.muted[_ngcontent-%COMP%] {\n color: #94a3b8;\n font-style: italic;\n}\n\n\n\n.detail-section[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.detail-section[_ngcontent-%COMP%] .status-badge.active[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.detail-section[_ngcontent-%COMP%] .status-badge.inactive[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n\n\n.detail-panel-actions[_ngcontent-%COMP%] {\n padding: 20px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n.detail-action-btn[_ngcontent-%COMP%] {\n padding: 12px 24px;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-action-btn.primary[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border: none;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-action-btn.primary[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%] {\n background: white;\n border: 2px solid #e2e8f0;\n color: #475569;\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%]:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n}\n\n\n\n@media (max-width: 520px) {\n .detail-panel[_ngcontent-%COMP%] {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible[_ngcontent-%COMP%] {\n right: 0;\n }\n\n .detail-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n\n[_nghost-%COMP%] .search-highlight, \n.search-highlight[_ngcontent-%COMP%] {\n background-color: #fef08a;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}"] });
|
|
1427
|
+
} }, dependencies: [i2.NgSelectOption, i2.ɵNgSelectMultipleOption, i2.DefaultValueAccessor, i2.NumberValueAccessor, i2.NgControlStatus, i2.MinValidator, i2.MaxValidator, i2.NgModel, i3.SplitterComponent, i3.SplitterPaneComponent, i4.LoadingComponent, i5.DatePipe, i6.HighlightSearchPipe], styles: ["\n\n\n\n\n\n\n\n.model-management-v2[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n\n\n.dashboard-header[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 22px;\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.item-count[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.header-controls[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.view-btn[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.view-btn.active[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.control-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n}\n\n.control-btn.primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n\n\nkendo-splitter[_ngcontent-%COMP%] {\n flex: 1;\n background: var(--mj-bg-surface-card);\n margin-top: 0;\n}\n\n[_nghost-%COMP%] .k-splitter {\n border: none;\n background: transparent;\n}\n\n[_nghost-%COMP%] .k-splitbar {\n background: var(--mj-border-default);\n width: 6px;\n}\n\n[_nghost-%COMP%] .k-splitbar:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n[_nghost-%COMP%] .k-pane {\n overflow: hidden;\n}\n\n\n\n.filter-panel[_ngcontent-%COMP%] {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n\n\n.filter-panel-header[_ngcontent-%COMP%] {\n padding: 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n}\n\n.filter-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 20px;\n border: 1px solid var(--mj-brand-accent);\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] .summary-value[_ngcontent-%COMP%] {\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .filter-summary-inline[_ngcontent-%COMP%] .summary-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.filter-panel-header[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n\n.filter-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n\n\n.filter-group[_ngcontent-%COMP%] {\n margin-bottom: 24px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-brand-primary);\n width: 16px;\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%], \n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: var(--mj-text-secondary);\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]:focus, \n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n\n\n.filter-input[_ngcontent-%COMP%], \n.filter-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: var(--mj-text-secondary);\n}\n\n.filter-input[_ngcontent-%COMP%]:focus, \n.filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.filter-select[_ngcontent-%COMP%] {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n\n\n.rank-filter-inputs[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n align-items: center;\n margin-top: 8px;\n}\n\n.rank-input[_ngcontent-%COMP%] {\n width: 70px;\n padding: 10px 12px;\n border: 2px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n text-align: center;\n background: var(--mj-bg-surface);\n transition: all 0.3s;\n box-sizing: border-box;\n -moz-appearance: textfield;\n}\n\n.rank-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.rank-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.rank-input[_ngcontent-%COMP%]::-webkit-inner-spin-button, \n.rank-input[_ngcontent-%COMP%]::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.rank-separator[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 600;\n}\n\n\n\n.filter-actions[_ngcontent-%COMP%] {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%] {\n width: 100%;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n color: var(--mj-text-muted);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions[_ngcontent-%COMP%] .reset-btn[_ngcontent-%COMP%] .fa-solid[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.filter-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n\n\n.content-area[_ngcontent-%COMP%] {\n height: 100%;\n padding: 28px;\n overflow-y: auto;\n background: var(--mj-bg-surface-card);\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 height: 100%;\n text-align: center;\n color: var(--mj-text-muted);\n padding: 60px 32px;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 80px;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n opacity: 1;\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 32px 0;\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n}\n\n\n\n.model-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.model-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid var(--mj-border-default);\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.model-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: var(--mj-brand-primary);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.model-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 20px 40px -15px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n transform: translateY(-4px);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.model-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n.model-card.expanded[_ngcontent-%COMP%] {\n box-shadow: 0 25px 50px -12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-color: var(--mj-brand-accent);\n}\n\n.model-card.expanded[_ngcontent-%COMP%]::before {\n opacity: 1;\n}\n\n.card-header[_ngcontent-%COMP%] {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background-color 0.2s;\n}\n\n.card-header[_ngcontent-%COMP%]:hover {\n background-color: var(--mj-bg-surface-card);\n}\n\n.model-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.model-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.model-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n font-size: 24px;\n}\n\n.model-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.model-name[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.model-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.meta-item.status-active[_ngcontent-%COMP%] {\n color: var(--mj-color-success-700);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.meta-item.status-active[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-success-700);\n}\n\n.meta-item.status-inactive[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n background: var(--mj-border-default);\n}\n\n.meta-item.status-inactive[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--mj-text-disabled);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon[_ngcontent-%COMP%]:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.expand-icon.rotated[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.card-body[_ngcontent-%COMP%] {\n padding: 0 24px 24px 24px;\n}\n\n.model-description[_ngcontent-%COMP%] {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: var(--mj-text-muted);\n}\n\n.model-description.text-muted[_ngcontent-%COMP%] {\n font-style: italic;\n color: var(--mj-text-disabled);\n}\n\n\n\n.expanded-content[_ngcontent-%COMP%] {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n animation: _ngcontent-%COMP%_slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.model-stats[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n}\n\n.stat-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value[_ngcontent-%COMP%] {\n font-size: 15px;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n\n\n.card-actions[_ngcontent-%COMP%] {\n padding: 18px 24px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-default);\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n transform: translateY(-1px);\n}\n\n.action-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border-color: transparent;\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.action-btn-primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n\n\n.model-list[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.data-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-brand-primary);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:last-child, \n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:nth-last-child(2) {\n cursor: default;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:last-child:hover, \n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:nth-last-child(2):hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted.desc[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n.data-table[_ngcontent-%COMP%] .sort-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.data-table[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%]:hover .sort-icon[_ngcontent-%COMP%] {\n opacity: 0.5;\n}\n\n.data-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.sorted[_ngcontent-%COMP%] .sort-icon[_ngcontent-%COMP%] {\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background-color 0.2s ease;\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.data-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 18px 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.name-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.name-cell[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n\n\n.rank-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.rank-badge.rank-high[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.rank-badge.rank-medium[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-color-warning-700);\n}\n\n.rank-badge.rank-low[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.rank-badge.rank-none[_ngcontent-%COMP%] {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-badge.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.status-badge.inactive[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n\n\n@media (max-width: 768px) {\n .dashboard-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info[_ngcontent-%COMP%] {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls[_ngcontent-%COMP%] {\n justify-content: center;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .model-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .model-stats[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .card-header[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .card-body[_ngcontent-%COMP%] {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions[_ngcontent-%COMP%] {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n\n\n\n.detail-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n z-index: 1000;\n opacity: 0;\n animation: _ngcontent-%COMP%_fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n to {\n opacity: 1;\n }\n}\n\n\n\n.detail-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n max-width: 90vw;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible[_ngcontent-%COMP%] {\n right: 0;\n}\n\n\n\n.detail-panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.detail-panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.detail-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n font-size: 24px;\n}\n\n.detail-title-info[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.detail-subtitle[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.detail-panel-close[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n}\n\n.detail-panel-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n\n\n.detail-panel-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n\n\n.detail-section[_ngcontent-%COMP%] {\n margin-bottom: 28px;\n}\n\n.detail-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.feature-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.feature-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 11px;\n}\n\n.detail-description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: var(--mj-text-secondary);\n}\n\n.detail-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n\n\n.detail-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-item.full-width[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-primary);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 13px;\n}\n\n.detail-value.muted[_ngcontent-%COMP%] {\n color: var(--mj-text-disabled);\n font-style: italic;\n}\n\n\n\n.detail-section[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.detail-section[_ngcontent-%COMP%] .status-badge.active[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.detail-section[_ngcontent-%COMP%] .status-badge.inactive[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n\n\n.detail-panel-actions[_ngcontent-%COMP%] {\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n.detail-action-btn[_ngcontent-%COMP%] {\n padding: 12px 24px;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-action-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.detail-action-btn.primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.detail-action-btn.secondary[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n\n\n@media (max-width: 520px) {\n .detail-panel[_ngcontent-%COMP%] {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible[_ngcontent-%COMP%] {\n right: 0;\n }\n\n .detail-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n}\n\n\n\n[_nghost-%COMP%] .search-highlight, \n.search-highlight[_ngcontent-%COMP%] {\n background-color: color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface));\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}"] });
|
|
1428
1428
|
};
|
|
1429
1429
|
ModelManagementComponent = __decorate([
|
|
1430
1430
|
RegisterClass(BaseResourceComponent, 'AIModelsResource')
|
|
@@ -1432,7 +1432,7 @@ ModelManagementComponent = __decorate([
|
|
|
1432
1432
|
export { ModelManagementComponent };
|
|
1433
1433
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ModelManagementComponent, [{
|
|
1434
1434
|
type: Component,
|
|
1435
|
-
args: [{ standalone: false, selector: 'app-model-management', template: "<div class=\"model-management-v2\">\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"currentLoadingMessage\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n AI Models\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilters()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (showFilters) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"item-count\">{{ filteredModels.length }} models</span>\n </div>\n\n <div class=\"header-controls\">\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"control-btn primary\"\n (click)=\"createNewModel()\"\n title=\"Create New Model\">\n <i class=\"fa-solid fa-plus\"></i>\n New Model\n </button>\n </div>\n </div>\n\n <kendo-splitter orientation=\"horizontal\">\n @if (showFilters) {\n <kendo-splitter-pane size=\"320\" min=\"250\" max=\"400\">\n <div class=\"filter-panel\">\n <div class=\"filter-panel-header\">\n <h3>Model Filters</h3>\n <div class=\"filter-summary-inline\">\n <span class=\"summary-value\">{{ filteredModels.length }}</span>\n <span class=\"summary-label\">of {{ models.length }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"toggleFilterPanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n \n <div class=\"filter-content\">\n <!-- Search Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-search\"></span>\n Name\n </label>\n <input \n type=\"text\"\n class=\"filter-input\"\n placeholder=\"Search models...\"\n [value]=\"searchTerm\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n </div>\n\n <!-- Sort By Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-sort\"></span>\n Sort By\n </label>\n <select class=\"filter-select\" [value]=\"sortBy\" (change)=\"onSortChange($any($event.target).value)\">\n @for (option of sortOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n </div>\n\n <!-- Vendor Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-building\"></span>\n Vendor\n </label>\n <select class=\"filter-select\" [value]=\"selectedVendor\" (change)=\"onVendorChange($any($event.target).value)\">\n <option value=\"all\">All Vendors</option>\n @for (vendor of vendors; track vendor.ID) {\n <option [value]=\"vendor.ID\">{{ vendor.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-microchip\"></span>\n Type\n </label>\n <select class=\"filter-select\" [value]=\"selectedType\" (change)=\"onTypeChange($any($event.target).value)\">\n <option value=\"all\">All Types</option>\n @for (type of modelTypes; track type.ID) {\n <option [value]=\"type.ID\">{{ type.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-toggle-on\"></span>\n Status\n </label>\n <select class=\"filter-select\" [value]=\"selectedStatus\" (change)=\"onStatusChange($any($event.target).value)\">\n <option value=\"all\">All Statuses</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Power Rank Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-bolt\"></span>\n Power Rank\n </label>\n <div class=\"rank-filter-inputs\">\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.min\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Min\"\n />\n <span class=\"rank-separator\">-</span>\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.max\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Max\"\n />\n </div>\n </div>\n\n <!-- Reset Button -->\n <div class=\"filter-actions\">\n <button class=\"reset-btn\" (click)=\"clearFilters()\" title=\"Reset all filters\">\n <span class=\"fa-solid fa-undo\"></span>\n Reset Filters\n </button>\n </div>\n </div>\n </div>\n </kendo-splitter-pane>\n }\n\n <kendo-splitter-pane>\n <div class=\"content-area\">\n @if (filteredModels.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-microchip fa-4x\"></i>\n <h3>No models found</h3>\n <p>{{ hasActiveFilters ? 'Try adjusting your filters' : 'Create your first AI model to get started' }}</p>\n @if (!hasActiveFilters) {\n <button class=\"primary-action\" (click)=\"createNewModel()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create First Model\n </button>\n }\n </div>\n } @else {\n @switch (viewMode) {\n @case ('grid') {\n <div class=\"model-grid\">\n @for (model of filteredModels; track model.ID) {\n <div class=\"model-card\" [class.expanded]=\"expandedModelId === model.ID\">\n <!-- Card Header -->\n <div class=\"card-header\" (click)=\"toggleModelExpansion(model.ID)\">\n <div class=\"model-info\">\n <div class=\"model-icon\">\n <i [class]=\"getModelIcon(model)\"></i>\n </div>\n <div class=\"model-details\">\n <h4 class=\"model-name\" [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></h4>\n <div class=\"model-meta\">\n @if (model.Vendor) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-building\"></i>\n {{ model.Vendor }}\n </span>\n }\n @if (model.AIModelType) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ model.AIModelType }}\n </span>\n }\n @if (model.IsActive) {\n <span class=\"meta-item status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"meta-item status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n </div>\n </div>\n </div>\n\n <i class=\"fa-solid fa-chevron-down expand-icon\"\n [class.rotated]=\"expandedModelId === model.ID\"></i>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (model.Description) {\n <p class=\"model-description\" [innerHTML]=\"model.Description | highlightSearch:searchTerm\"></p>\n } @else {\n <p class=\"model-description text-muted\">No description provided</p>\n }\n\n <!-- Expandable Content -->\n @if (expandedModelId === model.ID) {\n <div class=\"expanded-content\">\n <div class=\"model-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Power Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.PowerRank, 'power') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Speed Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.SpeedRank, 'speed') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Cost Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.CostRank, 'cost') }}</span>\n </div>\n @if (model.InputTokenLimit) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Token Limit</span>\n <span class=\"stat-value\">{{ formatTokenLimit(model.InputTokenLimit) }}</span>\n </div>\n }\n @if (model.APIName) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">API Name</span>\n <span class=\"stat-value\">{{ model.APIName }}</span>\n </div>\n }\n @if (model.DriverClass) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Driver</span>\n <span class=\"stat-value\">{{ model.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\">\n <button\n type=\"button\"\n class=\"action-btn\"\n (click)=\"showModelDetails(model, $event)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n \n @case ('list') {\n <div class=\"model-list\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th (click)=\"onSortChange('name')\"\n [class.sorted]=\"sortBy === 'name'\"\n [class.desc]=\"sortBy === 'name' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Name\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('vendor')\"\n [class.sorted]=\"sortBy === 'vendor'\"\n [class.desc]=\"sortBy === 'vendor' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Vendor\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('type')\"\n [class.sorted]=\"sortBy === 'type'\"\n [class.desc]=\"sortBy === 'type' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Type\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('powerRank')\"\n [class.sorted]=\"sortBy === 'powerRank'\"\n [class.desc]=\"sortBy === 'powerRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Power\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('speedRank')\"\n [class.sorted]=\"sortBy === 'speedRank'\"\n [class.desc]=\"sortBy === 'speedRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Speed\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('costRank')\"\n [class.sorted]=\"sortBy === 'costRank'\"\n [class.desc]=\"sortBy === 'costRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Cost\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th>Status</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (model of filteredModels; track model.ID) {\n <tr>\n <td>\n <div class=\"name-cell\">\n <i [class]=\"getModelIcon(model)\"></i>\n <span [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></span>\n </div>\n </td>\n <td>{{ model.Vendor || '-' }}</td>\n <td>{{ model.AIModelType }}</td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.PowerRank, 'power')\">\n {{ formatRank(model.PowerRank, 'power') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.SpeedRank, 'speed')\">\n {{ formatRank(model.SpeedRank, 'speed') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.CostRank, 'cost')\">\n {{ formatRank(model.CostRank, 'cost') }}\n </span>\n </td>\n <td>\n <span class=\"status-badge\" [class.active]=\"model.IsActive\" [class.inactive]=\"!model.IsActive\">\n {{ model.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <button class=\"action-button small\" (click)=\"showModelDetails(model)\" title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n\n <!-- Detail Panel Overlay -->\n @if (detailPanelVisible) {\n <div class=\"detail-panel-overlay\" (click)=\"closeDetailPanel()\"></div>\n }\n\n <!-- Detail Panel -->\n <div class=\"detail-panel\" [class.visible]=\"detailPanelVisible\">\n @if (selectedModel) {\n <!-- Panel Header -->\n <div class=\"detail-panel-header\">\n <div class=\"detail-panel-title\">\n <div class=\"detail-icon\">\n <i [class]=\"getModelIcon(selectedModel)\"></i>\n </div>\n <div class=\"detail-title-info\">\n <h3>{{ selectedModel.Name }}</h3>\n <span class=\"detail-subtitle\">{{ selectedModel.Vendor || 'AI Model' }}</span>\n </div>\n </div>\n <button class=\"detail-panel-close\" (click)=\"closeDetailPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Panel Content -->\n <div class=\"detail-panel-content\">\n <!-- Status Section -->\n <div class=\"detail-section\">\n <div class=\"detail-badges\">\n @if (selectedModel.IsActive) {\n <span class=\"status-badge status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"status-badge status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n @if (selectedModel.AIModelType) {\n <span class=\"feature-badge\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ selectedModel.AIModelType }}\n </span>\n }\n </div>\n </div>\n\n <!-- Description -->\n @if (selectedModel.Description) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h4>\n <p class=\"detail-description\">{{ selectedModel.Description }}</p>\n </div>\n }\n\n <!-- Ranking Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Rankings\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Power Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.PowerRank, 'power')\">\n {{ formatRank(selectedModel.PowerRank, 'power') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Speed Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.SpeedRank, 'speed')\">\n {{ formatRank(selectedModel.SpeedRank, 'speed') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Cost Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.CostRank, 'cost')\">\n {{ formatRank(selectedModel.CostRank, 'cost') }}\n </span>\n </div>\n </div>\n </div>\n\n <!-- Configuration Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Configuration\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Vendor</span>\n <span class=\"detail-value\">{{ selectedModel.Vendor || 'Unknown' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Model Type</span>\n <span class=\"detail-value\">{{ selectedModel.AIModelType || 'Unknown' }}</span>\n </div>\n @if (selectedModel.APIName) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">API Name</span>\n <span class=\"detail-value\">{{ selectedModel.APIName }}</span>\n </div>\n }\n @if (selectedModel.InputTokenLimit) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Input Token Limit</span>\n <span class=\"detail-value\">{{ formatTokenLimit(selectedModel.InputTokenLimit) }}</span>\n </div>\n }\n @if (selectedModel.SupportedResponseFormats) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Response Formats</span>\n <span class=\"detail-value\">{{ selectedModel.SupportedResponseFormats }}</span>\n </div>\n }\n @if (selectedModel.SupportsEffortLevel) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Supports Effort Level</span>\n <span class=\"detail-value\">Yes</span>\n </div>\n }\n @if (selectedModel.DriverClass) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Driver Class</span>\n <span class=\"detail-value\">{{ selectedModel.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Timestamps -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-clock\"></i>\n Timestamps\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Created</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_CreatedAt | date:'medium' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Updated</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Panel Actions -->\n <div class=\"detail-panel-actions\">\n <button\n type=\"button\"\n class=\"detail-action-btn primary\"\n (click)=\"openModelFromPanel()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n </div>\n }\n </div>\n }\n</div>", styles: ["/* ============================================\n AI Models Dashboard - World-Class Design\n Clean white header with indigo/purple accents\n ============================================ */\n\n/* Container */\n.model-management-v2 {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ed 100%);\n}\n\n/* Dashboard Header - Clean White Style */\n.dashboard-header {\n background: white;\n padding: 16px 24px;\n border-bottom: 1px solid #e0e6ed;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title i {\n color: #6366f1;\n font-size: 22px;\n}\n\n.filter-toggle-btn {\n background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn:hover {\n background: linear-gradient(135deg, #e9ecef 0%, #dee2e6 100%);\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn i {\n color: #6366f1;\n font-size: 14px;\n}\n\n.item-count {\n color: #6c757d;\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: #f8f9fa;\n border-radius: 20px;\n border: 1px solid #e9ecef;\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: #f8f9fa;\n border-radius: 8px;\n padding: 3px;\n border: 1px solid #dee2e6;\n}\n\n.view-btn {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: #6c757d;\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn:hover {\n color: #495057;\n}\n\n.view-btn.active {\n background: white;\n color: #6366f1;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn {\n background: white;\n border: 1px solid #dee2e6;\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: #495057;\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn:hover {\n background: #f8f9fa;\n border-color: #ced4da;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn i {\n font-size: 14px;\n}\n\n.control-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #4f46e5 100%);\n border-color: #4f46e5;\n color: white;\n}\n\n.control-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #4338ca 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);\n}\n\n/* Splitter */\nkendo-splitter {\n flex: 1;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n margin-top: 0;\n}\n\n:host ::ng-deep .k-splitter {\n border: none;\n background: transparent;\n}\n\n:host ::ng-deep .k-splitbar {\n background: #e2e8f0;\n width: 6px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n background: #c7d2fe;\n}\n\n:host ::ng-deep .k-pane {\n overflow: hidden;\n}\n\n/* Filter Panel */\n.filter-panel {\n height: 100%;\n background: white;\n border-right: 1px solid #e5e7eb;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Header */\n.filter-panel-header {\n padding: 20px;\n border-bottom: 1px solid #f1f5f9;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.filter-panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: #1e293b;\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header .filter-summary-inline {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: linear-gradient(135deg, #ede9fe 0%, #ddd6fe 100%);\n border-radius: 20px;\n border: 1px solid #c4b5fd;\n}\n\n.filter-panel-header .filter-summary-inline .summary-value {\n font-weight: 700;\n color: #6366f1;\n}\n\n.filter-panel-header .filter-summary-inline .summary-label {\n color: #7c3aed;\n font-weight: 500;\n}\n\n.filter-panel-header .close-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: #94a3b8;\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header .close-btn:hover {\n background: #f1f5f9;\n color: #475569;\n}\n\n.filter-panel-header .close-btn .fa-solid {\n font-size: 14px;\n}\n\n/* Content Area */\n.filter-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n/* Filter Groups */\n.filter-group {\n margin-bottom: 24px;\n}\n\n.filter-group .filter-label {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group .filter-label .fa-solid {\n font-size: 13px;\n color: #6366f1;\n width: 16px;\n}\n\n.filter-group .filter-input,\n.filter-group .filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-group .filter-input:focus,\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-group .filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-group .filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Legacy support for non-scoped selectors */\n.filter-input,\n.filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n font-size: 14px;\n background: white;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: #334155;\n}\n\n.filter-input:focus,\n.filter-select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);\n}\n\n.filter-input::placeholder {\n color: #94a3b8;\n}\n\n.filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Rank Filter */\n.rank-filter-inputs {\n display: flex;\n gap: 10px;\n align-items: center;\n margin-top: 8px;\n}\n\n.rank-input {\n width: 70px;\n padding: 10px 12px;\n border: 2px solid #e2e8f0;\n border-radius: 8px;\n font-size: 14px;\n text-align: center;\n background: white;\n transition: all 0.3s;\n box-sizing: border-box;\n -moz-appearance: textfield;\n}\n\n.rank-input:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);\n}\n\n.rank-input::placeholder {\n color: #94a3b8;\n font-size: 12px;\n}\n\n.rank-input::-webkit-inner-spin-button,\n.rank-input::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.rank-separator {\n color: #64748b;\n font-size: 13px;\n font-weight: 600;\n}\n\n/* Filter Actions */\n.filter-actions {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid #f1f5f9;\n}\n\n.filter-actions .reset-btn {\n width: 100%;\n padding: 12px 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid #e2e8f0;\n border-radius: 10px;\n color: #64748b;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions .reset-btn:hover {\n background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);\n border-color: #cbd5e1;\n color: #475569;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions .reset-btn .fa-solid {\n font-size: 13px;\n}\n\n/* Scrollbar Styling */\n.filter-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content::-webkit-scrollbar-track {\n background: #f8fafc;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb {\n background: #cbd5e1;\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb:hover {\n background: #94a3b8;\n}\n\n/* Content Area */\n.content-area {\n height: 100%;\n padding: 28px;\n overflow-y: auto;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 50%, #e8f0fe 100%);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: #64748b;\n padding: 60px 32px;\n}\n\n.empty-state i {\n font-size: 80px;\n background: linear-gradient(135deg, #c7d2fe 0%, #ddd6fe 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n opacity: 1;\n}\n\n.empty-state h3 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.empty-state p {\n margin: 0 0 32px 0;\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n}\n\n/* Grid View */\n.model-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.model-card {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid #e2e8f0;\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.model-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: linear-gradient(90deg, #6366f1 0%, #8b5cf6 50%, #a78bfa 100%);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.model-card:hover {\n box-shadow: 0 20px 40px -15px rgba(99, 102, 241, 0.25);\n transform: translateY(-4px);\n border-color: #c7d2fe;\n}\n\n.model-card:hover::before {\n opacity: 1;\n}\n\n.model-card.expanded {\n box-shadow: 0 25px 50px -12px rgba(99, 102, 241, 0.3);\n border-color: #a5b4fc;\n}\n\n.model-card.expanded::before {\n opacity: 1;\n}\n\n.card-header {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s;\n}\n\n.card-header:hover {\n background-color: #fafbfc;\n}\n\n.model-info {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.model-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.model-icon i {\n color: white;\n font-size: 24px;\n}\n\n.model-details {\n flex: 1;\n min-width: 0;\n}\n\n.model-name {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.model-meta {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n font-size: 13px;\n color: #64748b;\n display: flex;\n align-items: center;\n gap: 6px;\n background: #f1f5f9;\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n color: #6366f1;\n}\n\n.meta-item.status-active {\n color: #059669;\n background: #d1fae5;\n}\n\n.meta-item.status-active i {\n color: #059669;\n}\n\n.meta-item.status-inactive {\n color: #64748b;\n background: #e2e8f0;\n}\n\n.meta-item.status-inactive i {\n color: #64748b;\n}\n\n.expand-icon {\n font-size: 16px;\n color: #94a3b8;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon:hover {\n color: #6366f1;\n background: #f1f5f9;\n}\n\n.expand-icon.rotated {\n transform: rotate(180deg);\n color: #6366f1;\n}\n\n.card-body {\n padding: 0 24px 24px 24px;\n}\n\n.model-description {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: #64748b;\n}\n\n.model-description.text-muted {\n font-style: italic;\n color: #94a3b8;\n}\n\n/* Expanded Content */\n.expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid #e2e8f0;\n animation: slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.model-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.stat-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value {\n font-size: 15px;\n color: #1e293b;\n font-weight: 600;\n}\n\n/* Card Actions */\n.card-actions {\n padding: 18px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn {\n background: white;\n border: 2px solid #e2e8f0;\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: #475569;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n transform: translateY(-1px);\n}\n\n.action-btn-primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border-color: transparent;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.action-btn-primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n/* List View */\n.model-list {\n background: white;\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid #e2e8f0;\n overflow: hidden;\n}\n\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table thead {\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n}\n\n.data-table thead tr {\n border-bottom: 2px solid #e2e8f0;\n}\n\n.data-table thead th {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover {\n background: #e2e8f0;\n color: #6366f1;\n}\n\n.data-table thead th:last-child,\n.data-table thead th:nth-last-child(2) {\n cursor: default;\n}\n\n.data-table thead th:last-child:hover,\n.data-table thead th:nth-last-child(2):hover {\n background: transparent;\n color: #475569;\n}\n\n.data-table thead th.sorted {\n color: #6366f1;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n}\n\n.data-table thead th.sorted.desc .sort-icon {\n transform: rotate(180deg);\n}\n\n.data-table .sort-header {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.data-table .sort-icon {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover .sort-icon {\n opacity: 0.5;\n}\n\n.data-table thead th.sorted .sort-icon {\n opacity: 1;\n color: #6366f1;\n}\n\n.data-table tbody tr {\n border-bottom: 1px solid #f1f5f9;\n transition: background-color 0.2s ease;\n}\n\n.data-table tbody tr:last-child {\n border-bottom: none;\n}\n\n.data-table tbody tr:hover {\n background: linear-gradient(135deg, #fafbfc 0%, #f8fafc 100%);\n}\n\n.data-table tbody td {\n padding: 18px 20px;\n font-size: 14px;\n color: #475569;\n}\n\n.name-cell {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n color: #1e293b;\n}\n\n.name-cell i {\n color: #6366f1;\n font-size: 18px;\n}\n\n/* Rank Badge */\n.rank-badge {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.rank-badge.rank-high {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.rank-badge.rank-medium {\n background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);\n color: #b45309;\n}\n\n.rank-badge.rank-low {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.rank-badge.rank-none {\n background: linear-gradient(135deg, #e2e8f0 0%, #cbd5e1 100%);\n color: #475569;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-badge.active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .dashboard-header {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls {\n justify-content: center;\n }\n\n .content-area {\n padding: 16px;\n }\n\n .model-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .model-stats {\n grid-template-columns: 1fr;\n }\n\n .card-header {\n padding: 18px;\n }\n\n .card-body {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n/* ============================================\n Detail Panel - Slide-in Panel\n ============================================ */\n\n/* Detail Panel Overlay */\n.detail-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(15, 23, 42, 0.5);\n backdrop-filter: blur(4px);\n z-index: 1000;\n opacity: 0;\n animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes fadeIn {\n to {\n opacity: 1;\n }\n}\n\n/* Detail Panel */\n.detail-panel {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n max-width: 90vw;\n height: 100vh;\n background: white;\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible {\n right: 0;\n}\n\n/* Detail Panel Header */\n.detail-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-bottom: 1px solid #e2e8f0;\n flex-shrink: 0;\n}\n\n.detail-panel-title {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-icon i {\n color: white;\n font-size: 24px;\n}\n\n.detail-title-info h3 {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: #1e293b;\n}\n\n.detail-subtitle {\n font-size: 13px;\n color: #64748b;\n font-weight: 500;\n}\n\n.detail-panel-close {\n background: white;\n border: 1px solid #e2e8f0;\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: #64748b;\n}\n\n.detail-panel-close:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n color: #1e293b;\n}\n\n/* Detail Panel Content */\n.detail-panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* Detail Section */\n.detail-section {\n margin-bottom: 28px;\n}\n\n.detail-section:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge.status-active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.status-badge.status-inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n.feature-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: linear-gradient(135deg, #eef2ff 0%, #e0e7ff 100%);\n color: #4f46e5;\n}\n\n.feature-badge i {\n font-size: 11px;\n}\n\n.detail-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: #475569;\n}\n\n.detail-section-title {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 700;\n color: #475569;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-section-title i {\n color: #6366f1;\n font-size: 14px;\n}\n\n/* Detail Grid */\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column {\n grid-template-columns: 1fr;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-radius: 12px;\n border: 1px solid #e2e8f0;\n}\n\n.detail-item.full-width {\n grid-column: 1 / -1;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n color: #64748b;\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: #1e293b;\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value i {\n font-size: 13px;\n}\n\n.detail-value.muted {\n color: #94a3b8;\n font-style: italic;\n}\n\n/* Status Badges in Detail Panel */\n.detail-section .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.detail-section .status-badge.active {\n background: linear-gradient(135deg, #d1fae5 0%, #a7f3d0 100%);\n color: #047857;\n}\n\n.detail-section .status-badge.inactive {\n background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);\n color: #b91c1c;\n}\n\n/* Detail Panel Actions */\n.detail-panel-actions {\n padding: 20px 24px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border-top: 1px solid #e2e8f0;\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n.detail-action-btn {\n padding: 12px 24px;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-action-btn.primary {\n background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);\n border: none;\n color: white;\n box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);\n}\n\n.detail-action-btn.primary:hover {\n background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(99, 102, 241, 0.4);\n}\n\n.detail-action-btn.secondary {\n background: white;\n border: 2px solid #e2e8f0;\n color: #475569;\n}\n\n.detail-action-btn.secondary:hover {\n background: #f8fafc;\n border-color: #6366f1;\n color: #6366f1;\n}\n\n/* Responsive adjustments for detail panel */\n@media (max-width: 520px) {\n .detail-panel {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible {\n right: 0;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* Search Highlight */\n:host ::ng-deep .search-highlight,\n.search-highlight {\n background-color: #fef08a;\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}\n"] }]
|
|
1435
|
+
args: [{ standalone: false, selector: 'app-model-management', template: "<div class=\"model-management-v2\">\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading [text]=\"currentLoadingMessage\" size=\"large\"></mj-loading>\n </div>\n } @else {\n <div class=\"dashboard-header\">\n <div class=\"header-info\">\n <h2 class=\"dashboard-title\">\n <i class=\"fa-solid fa-microchip\"></i>\n AI Models\n </h2>\n <button\n type=\"button\"\n class=\"filter-toggle-btn\"\n (click)=\"toggleFilters()\"\n title=\"Toggle Filters\">\n <i class=\"fa-solid fa-filter\"></i>\n @if (showFilters) {\n Hide Filters\n } @else {\n Show Filters\n }\n </button>\n <span class=\"item-count\">{{ filteredModels.length }} models</span>\n </div>\n\n <div class=\"header-controls\">\n <div class=\"view-toggle\">\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'grid'\"\n (click)=\"setViewMode('grid')\"\n title=\"Grid View\">\n <i class=\"fa-solid fa-grip\"></i>\n </button>\n <button\n type=\"button\"\n class=\"view-btn\"\n [class.active]=\"viewMode === 'list'\"\n (click)=\"setViewMode('list')\"\n title=\"List View\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"control-btn primary\"\n (click)=\"createNewModel()\"\n title=\"Create New Model\">\n <i class=\"fa-solid fa-plus\"></i>\n New Model\n </button>\n </div>\n </div>\n\n <kendo-splitter orientation=\"horizontal\">\n @if (showFilters) {\n <kendo-splitter-pane size=\"320\" min=\"250\" max=\"400\">\n <div class=\"filter-panel\">\n <div class=\"filter-panel-header\">\n <h3>Model Filters</h3>\n <div class=\"filter-summary-inline\">\n <span class=\"summary-value\">{{ filteredModels.length }}</span>\n <span class=\"summary-label\">of {{ models.length }}</span>\n </div>\n <button class=\"close-btn\" (click)=\"toggleFilterPanel()\">\n <span class=\"fa-solid fa-times\"></span>\n </button>\n </div>\n \n <div class=\"filter-content\">\n <!-- Search Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-search\"></span>\n Name\n </label>\n <input \n type=\"text\"\n class=\"filter-input\"\n placeholder=\"Search models...\"\n [value]=\"searchTerm\"\n (input)=\"onSearchChange($any($event.target).value)\"\n />\n </div>\n\n <!-- Sort By Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-sort\"></span>\n Sort By\n </label>\n <select class=\"filter-select\" [value]=\"sortBy\" (change)=\"onSortChange($any($event.target).value)\">\n @for (option of sortOptions; track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n </div>\n\n <!-- Vendor Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-building\"></span>\n Vendor\n </label>\n <select class=\"filter-select\" [value]=\"selectedVendor\" (change)=\"onVendorChange($any($event.target).value)\">\n <option value=\"all\">All Vendors</option>\n @for (vendor of vendors; track vendor.ID) {\n <option [value]=\"vendor.ID\">{{ vendor.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Type Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-microchip\"></span>\n Type\n </label>\n <select class=\"filter-select\" [value]=\"selectedType\" (change)=\"onTypeChange($any($event.target).value)\">\n <option value=\"all\">All Types</option>\n @for (type of modelTypes; track type.ID) {\n <option [value]=\"type.ID\">{{ type.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-toggle-on\"></span>\n Status\n </label>\n <select class=\"filter-select\" [value]=\"selectedStatus\" (change)=\"onStatusChange($any($event.target).value)\">\n <option value=\"all\">All Statuses</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Power Rank Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">\n <span class=\"fa-solid fa-bolt\"></span>\n Power Rank\n </label>\n <div class=\"rank-filter-inputs\">\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.min\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Min\"\n />\n <span class=\"rank-separator\">-</span>\n <input \n type=\"number\" \n min=\"0\" \n [max]=\"maxPowerRank\" \n [(ngModel)]=\"powerRankRange.max\"\n (change)=\"validateAndApplyRankFilters('power')\"\n class=\"rank-input\"\n placeholder=\"Max\"\n />\n </div>\n </div>\n\n <!-- Reset Button -->\n <div class=\"filter-actions\">\n <button class=\"reset-btn\" (click)=\"clearFilters()\" title=\"Reset all filters\">\n <span class=\"fa-solid fa-undo\"></span>\n Reset Filters\n </button>\n </div>\n </div>\n </div>\n </kendo-splitter-pane>\n }\n\n <kendo-splitter-pane>\n <div class=\"content-area\">\n @if (filteredModels.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-microchip fa-4x\"></i>\n <h3>No models found</h3>\n <p>{{ hasActiveFilters ? 'Try adjusting your filters' : 'Create your first AI model to get started' }}</p>\n @if (!hasActiveFilters) {\n <button class=\"primary-action\" (click)=\"createNewModel()\">\n <i class=\"fa-solid fa-plus\"></i>\n Create First Model\n </button>\n }\n </div>\n } @else {\n @switch (viewMode) {\n @case ('grid') {\n <div class=\"model-grid\">\n @for (model of filteredModels; track model.ID) {\n <div class=\"model-card\" [class.expanded]=\"expandedModelId === model.ID\">\n <!-- Card Header -->\n <div class=\"card-header\" (click)=\"toggleModelExpansion(model.ID)\">\n <div class=\"model-info\">\n <div class=\"model-icon\">\n <i [class]=\"getModelIcon(model)\"></i>\n </div>\n <div class=\"model-details\">\n <h4 class=\"model-name\" [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></h4>\n <div class=\"model-meta\">\n @if (model.Vendor) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-building\"></i>\n {{ model.Vendor }}\n </span>\n }\n @if (model.AIModelType) {\n <span class=\"meta-item\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ model.AIModelType }}\n </span>\n }\n @if (model.IsActive) {\n <span class=\"meta-item status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"meta-item status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n </div>\n </div>\n </div>\n\n <i class=\"fa-solid fa-chevron-down expand-icon\"\n [class.rotated]=\"expandedModelId === model.ID\"></i>\n </div>\n\n <!-- Card Body -->\n <div class=\"card-body\">\n @if (model.Description) {\n <p class=\"model-description\" [innerHTML]=\"model.Description | highlightSearch:searchTerm\"></p>\n } @else {\n <p class=\"model-description text-muted\">No description provided</p>\n }\n\n <!-- Expandable Content -->\n @if (expandedModelId === model.ID) {\n <div class=\"expanded-content\">\n <div class=\"model-stats\">\n <div class=\"stat-item\">\n <span class=\"stat-label\">Power Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.PowerRank, 'power') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Speed Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.SpeedRank, 'speed') }}</span>\n </div>\n <div class=\"stat-item\">\n <span class=\"stat-label\">Cost Rank</span>\n <span class=\"stat-value\">{{ formatRank(model.CostRank, 'cost') }}</span>\n </div>\n @if (model.InputTokenLimit) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Token Limit</span>\n <span class=\"stat-value\">{{ formatTokenLimit(model.InputTokenLimit) }}</span>\n </div>\n }\n @if (model.APIName) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">API Name</span>\n <span class=\"stat-value\">{{ model.APIName }}</span>\n </div>\n }\n @if (model.DriverClass) {\n <div class=\"stat-item\">\n <span class=\"stat-label\">Driver</span>\n <span class=\"stat-value\">{{ model.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Card Actions -->\n <div class=\"card-actions\">\n <button\n type=\"button\"\n class=\"action-btn\"\n (click)=\"showModelDetails(model, $event)\"\n title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n Details\n </button>\n </div>\n </div>\n }\n </div>\n }\n \n @case ('list') {\n <div class=\"model-list\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th (click)=\"onSortChange('name')\"\n [class.sorted]=\"sortBy === 'name'\"\n [class.desc]=\"sortBy === 'name' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Name\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('vendor')\"\n [class.sorted]=\"sortBy === 'vendor'\"\n [class.desc]=\"sortBy === 'vendor' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Vendor\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('type')\"\n [class.sorted]=\"sortBy === 'type'\"\n [class.desc]=\"sortBy === 'type' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Type\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('powerRank')\"\n [class.sorted]=\"sortBy === 'powerRank'\"\n [class.desc]=\"sortBy === 'powerRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Power\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('speedRank')\"\n [class.sorted]=\"sortBy === 'speedRank'\"\n [class.desc]=\"sortBy === 'speedRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Speed\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th (click)=\"onSortChange('costRank')\"\n [class.sorted]=\"sortBy === 'costRank'\"\n [class.desc]=\"sortBy === 'costRank' && sortDirection === 'desc'\">\n <span class=\"sort-header\">\n Cost\n <i class=\"fa-solid fa-chevron-up sort-icon\"></i>\n </span>\n </th>\n <th>Status</th>\n <th>Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (model of filteredModels; track model.ID) {\n <tr>\n <td>\n <div class=\"name-cell\">\n <i [class]=\"getModelIcon(model)\"></i>\n <span [innerHTML]=\"(model.Name || 'Unnamed Model') | highlightSearch:searchTerm\"></span>\n </div>\n </td>\n <td>{{ model.Vendor || '-' }}</td>\n <td>{{ model.AIModelType }}</td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.PowerRank, 'power')\">\n {{ formatRank(model.PowerRank, 'power') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.SpeedRank, 'speed')\">\n {{ formatRank(model.SpeedRank, 'speed') }}\n </span>\n </td>\n <td>\n <span class=\"rank-badge\" [class]=\"getRankClass(model.CostRank, 'cost')\">\n {{ formatRank(model.CostRank, 'cost') }}\n </span>\n </td>\n <td>\n <span class=\"status-badge\" [class.active]=\"model.IsActive\" [class.inactive]=\"!model.IsActive\">\n {{ model.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <button class=\"action-button small\" (click)=\"showModelDetails(model)\" title=\"View Details\">\n <i class=\"fa-solid fa-eye\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n }\n }\n </div>\n </kendo-splitter-pane>\n </kendo-splitter>\n\n <!-- Detail Panel Overlay -->\n @if (detailPanelVisible) {\n <div class=\"detail-panel-overlay\" (click)=\"closeDetailPanel()\"></div>\n }\n\n <!-- Detail Panel -->\n <div class=\"detail-panel\" [class.visible]=\"detailPanelVisible\">\n @if (selectedModel) {\n <!-- Panel Header -->\n <div class=\"detail-panel-header\">\n <div class=\"detail-panel-title\">\n <div class=\"detail-icon\">\n <i [class]=\"getModelIcon(selectedModel)\"></i>\n </div>\n <div class=\"detail-title-info\">\n <h3>{{ selectedModel.Name }}</h3>\n <span class=\"detail-subtitle\">{{ selectedModel.Vendor || 'AI Model' }}</span>\n </div>\n </div>\n <button class=\"detail-panel-close\" (click)=\"closeDetailPanel()\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Panel Content -->\n <div class=\"detail-panel-content\">\n <!-- Status Section -->\n <div class=\"detail-section\">\n <div class=\"detail-badges\">\n @if (selectedModel.IsActive) {\n <span class=\"status-badge status-active\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Active\n </span>\n } @else {\n <span class=\"status-badge status-inactive\">\n <i class=\"fa-solid fa-circle\" style=\"font-size: 8px;\"></i>\n Inactive\n </span>\n }\n @if (selectedModel.AIModelType) {\n <span class=\"feature-badge\">\n <i class=\"fa-solid fa-microchip\"></i>\n {{ selectedModel.AIModelType }}\n </span>\n }\n </div>\n </div>\n\n <!-- Description -->\n @if (selectedModel.Description) {\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-align-left\"></i>\n Description\n </h4>\n <p class=\"detail-description\">{{ selectedModel.Description }}</p>\n </div>\n }\n\n <!-- Ranking Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-chart-bar\"></i>\n Rankings\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Power Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.PowerRank, 'power')\">\n {{ formatRank(selectedModel.PowerRank, 'power') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Speed Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.SpeedRank, 'speed')\">\n {{ formatRank(selectedModel.SpeedRank, 'speed') }}\n </span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Cost Rank</span>\n <span class=\"detail-value rank-badge\" [class]=\"getRankClass(selectedModel.CostRank, 'cost')\">\n {{ formatRank(selectedModel.CostRank, 'cost') }}\n </span>\n </div>\n </div>\n </div>\n\n <!-- Configuration Details -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-cog\"></i>\n Configuration\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Vendor</span>\n <span class=\"detail-value\">{{ selectedModel.Vendor || 'Unknown' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Model Type</span>\n <span class=\"detail-value\">{{ selectedModel.AIModelType || 'Unknown' }}</span>\n </div>\n @if (selectedModel.APIName) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">API Name</span>\n <span class=\"detail-value\">{{ selectedModel.APIName }}</span>\n </div>\n }\n @if (selectedModel.InputTokenLimit) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Input Token Limit</span>\n <span class=\"detail-value\">{{ formatTokenLimit(selectedModel.InputTokenLimit) }}</span>\n </div>\n }\n @if (selectedModel.SupportedResponseFormats) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Response Formats</span>\n <span class=\"detail-value\">{{ selectedModel.SupportedResponseFormats }}</span>\n </div>\n }\n @if (selectedModel.SupportsEffortLevel) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Supports Effort Level</span>\n <span class=\"detail-value\">Yes</span>\n </div>\n }\n @if (selectedModel.DriverClass) {\n <div class=\"detail-item\">\n <span class=\"detail-label\">Driver Class</span>\n <span class=\"detail-value\">{{ selectedModel.DriverClass }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Timestamps -->\n <div class=\"detail-section\">\n <h4 class=\"detail-section-title\">\n <i class=\"fa-solid fa-clock\"></i>\n Timestamps\n </h4>\n <div class=\"detail-grid\">\n <div class=\"detail-item\">\n <span class=\"detail-label\">Created</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_CreatedAt | date:'medium' }}</span>\n </div>\n <div class=\"detail-item\">\n <span class=\"detail-label\">Updated</span>\n <span class=\"detail-value\">{{ selectedModel.__mj_UpdatedAt | date:'medium' }}</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Panel Actions -->\n <div class=\"detail-panel-actions\">\n <button\n type=\"button\"\n class=\"detail-action-btn primary\"\n (click)=\"openModelFromPanel()\">\n <i class=\"fa-solid fa-external-link-alt\"></i>\n Open Full Record\n </button>\n </div>\n }\n </div>\n }\n</div>", styles: ["/* ============================================\n AI Models Dashboard - World-Class Design\n Clean header with brand blue accents\n ============================================ */\n\n/* Container */\n.model-management-v2 {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-surface-card);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100%;\n background: var(--mj-bg-surface-card);\n}\n\n/* Dashboard Header - Clean White Style */\n.dashboard-header {\n background: var(--mj-bg-surface);\n padding: 16px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n position: relative;\n z-index: 10;\n}\n\n.header-info {\n display: flex;\n align-items: center;\n gap: 20px;\n}\n\n.dashboard-title {\n margin: 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.dashboard-title i {\n color: var(--mj-brand-primary);\n font-size: 22px;\n}\n\n.filter-toggle-btn {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.filter-toggle-btn:hover {\n background: var(--mj-border-default);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\n}\n\n.filter-toggle-btn i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n.item-count {\n color: var(--mj-text-muted);\n font-size: 14px;\n font-weight: 500;\n padding: 6px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: 20px;\n border: 1px solid var(--mj-border-default);\n}\n\n.header-controls {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n/* View Toggle */\n.view-toggle {\n display: flex;\n background: var(--mj-bg-surface-card);\n border-radius: 8px;\n padding: 3px;\n border: 1px solid var(--mj-border-default);\n}\n\n.view-btn {\n background: transparent;\n border: none;\n padding: 8px 14px;\n border-radius: 6px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n font-size: 15px;\n}\n\n.view-btn:hover {\n color: var(--mj-text-secondary);\n}\n\n.view-btn.active {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n padding: 10px 18px;\n border-radius: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.control-btn:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.control-btn i {\n font-size: 14px;\n}\n\n.control-btn.primary {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary-hover);\n color: var(--mj-text-inverse);\n}\n\n.control-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 35%, transparent);\n}\n\n/* Splitter */\nkendo-splitter {\n flex: 1;\n background: var(--mj-bg-surface-card);\n margin-top: 0;\n}\n\n:host ::ng-deep .k-splitter {\n border: none;\n background: transparent;\n}\n\n:host ::ng-deep .k-splitbar {\n background: var(--mj-border-default);\n width: 6px;\n}\n\n:host ::ng-deep .k-splitbar:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n:host ::ng-deep .k-pane {\n overflow: hidden;\n}\n\n/* Filter Panel */\n.filter-panel {\n height: 100%;\n background: var(--mj-bg-surface);\n border-right: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\n/* Header */\n.filter-panel-header {\n padding: 20px;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n}\n\n.filter-panel-header h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--mj-text-primary);\n flex: 1;\n letter-spacing: -0.02em;\n}\n\n.filter-panel-header .filter-summary-inline {\n display: flex;\n align-items: baseline;\n gap: 4px;\n margin-right: 16px;\n font-size: 13px;\n padding: 6px 12px;\n background: color-mix(in srgb, var(--mj-brand-primary) 15%, var(--mj-bg-surface));\n border-radius: 20px;\n border: 1px solid var(--mj-brand-accent);\n}\n\n.filter-panel-header .filter-summary-inline .summary-value {\n font-weight: 700;\n color: var(--mj-brand-primary);\n}\n\n.filter-panel-header .filter-summary-inline .summary-label {\n color: var(--mj-brand-primary);\n font-weight: 500;\n}\n\n.filter-panel-header .close-btn {\n background: transparent;\n border: none;\n padding: 8px;\n cursor: pointer;\n color: var(--mj-text-disabled);\n border-radius: 8px;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-panel-header .close-btn:hover {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.filter-panel-header .close-btn .fa-solid {\n font-size: 14px;\n}\n\n/* Content Area */\n.filter-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n padding: 20px;\n}\n\n/* Filter Groups */\n.filter-group {\n margin-bottom: 24px;\n}\n\n.filter-group .filter-label {\n display: flex;\n align-items: center;\n gap: 10px;\n margin-bottom: 10px;\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.75px;\n}\n\n.filter-group .filter-label .fa-solid {\n font-size: 13px;\n color: var(--mj-brand-primary);\n width: 16px;\n}\n\n.filter-group .filter-input,\n.filter-group .filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: var(--mj-text-secondary);\n}\n\n.filter-group .filter-input:focus,\n.filter-group .filter-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-group .filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.filter-group .filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Legacy support for non-scoped selectors */\n.filter-input,\n.filter-select {\n width: 100%;\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n font-size: 14px;\n background: var(--mj-bg-surface);\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n color: var(--mj-text-secondary);\n}\n\n.filter-input:focus,\n.filter-select:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.filter-input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n.filter-select {\n cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M2.5 4.5L6 8l3.5-3.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat;\n background-position: right 14px center;\n padding-right: 36px;\n}\n\n/* Rank Filter */\n.rank-filter-inputs {\n display: flex;\n gap: 10px;\n align-items: center;\n margin-top: 8px;\n}\n\n.rank-input {\n width: 70px;\n padding: 10px 12px;\n border: 2px solid var(--mj-border-default);\n border-radius: 8px;\n font-size: 14px;\n text-align: center;\n background: var(--mj-bg-surface);\n transition: all 0.3s;\n box-sizing: border-box;\n -moz-appearance: textfield;\n}\n\n.rank-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.rank-input::placeholder {\n color: var(--mj-text-disabled);\n font-size: 12px;\n}\n\n.rank-input::-webkit-inner-spin-button,\n.rank-input::-webkit-outer-spin-button {\n -webkit-appearance: none;\n margin: 0;\n}\n\n.rank-separator {\n color: var(--mj-text-muted);\n font-size: 13px;\n font-weight: 600;\n}\n\n/* Filter Actions */\n.filter-actions {\n margin-top: 28px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-bg-surface-sunken);\n}\n\n.filter-actions .reset-btn {\n width: 100%;\n padding: 12px 16px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n color: var(--mj-text-muted);\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 10px;\n transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n box-sizing: border-box;\n}\n\n.filter-actions .reset-btn:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-secondary);\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n}\n\n.filter-actions .reset-btn .fa-solid {\n font-size: 13px;\n}\n\n/* Scrollbar Styling */\n.filter-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.filter-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-card);\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.filter-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-disabled);\n}\n\n/* Content Area */\n.content-area {\n height: 100%;\n padding: 28px;\n overflow-y: auto;\n background: var(--mj-bg-surface-card);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n text-align: center;\n color: var(--mj-text-muted);\n padding: 60px 32px;\n}\n\n.empty-state i {\n font-size: 80px;\n background: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n margin-bottom: 28px;\n opacity: 1;\n}\n\n.empty-state h3 {\n margin: 0 0 12px 0;\n font-size: 24px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.empty-state p {\n margin: 0 0 32px 0;\n font-size: 16px;\n line-height: 1.6;\n max-width: 420px;\n}\n\n/* Grid View */\n.model-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));\n gap: 24px;\n}\n\n.model-card {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05), 0 2px 4px -1px rgba(0, 0, 0, 0.03);\n border: 1px solid var(--mj-border-default);\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n position: relative;\n}\n\n.model-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 4px;\n background: var(--mj-brand-primary);\n opacity: 0;\n transition: opacity 0.3s ease;\n}\n\n.model-card:hover {\n box-shadow: 0 20px 40px -15px color-mix(in srgb, var(--mj-brand-primary) 25%, transparent);\n transform: translateY(-4px);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-bg-surface));\n}\n\n.model-card:hover::before {\n opacity: 1;\n}\n\n.model-card.expanded {\n box-shadow: 0 25px 50px -12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n border-color: var(--mj-brand-accent);\n}\n\n.model-card.expanded::before {\n opacity: 1;\n}\n\n.card-header {\n padding: 24px;\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n cursor: pointer;\n user-select: none;\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background-color 0.2s;\n}\n\n.card-header:hover {\n background-color: var(--mj-bg-surface-card);\n}\n\n.model-info {\n display: flex;\n gap: 18px;\n flex: 1;\n}\n\n.model-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.model-icon i {\n color: var(--mj-text-inverse);\n font-size: 24px;\n}\n\n.model-details {\n flex: 1;\n min-width: 0;\n}\n\n.model-name {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--mj-text-primary);\n margin-bottom: 8px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.model-meta {\n display: flex;\n gap: 14px;\n flex-wrap: wrap;\n}\n\n.meta-item {\n font-size: 13px;\n color: var(--mj-text-muted);\n display: flex;\n align-items: center;\n gap: 6px;\n background: var(--mj-bg-surface-sunken);\n padding: 4px 10px;\n border-radius: 6px;\n}\n\n.meta-item i {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.meta-item.status-active {\n color: var(--mj-color-success-700);\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.meta-item.status-active i {\n color: var(--mj-color-success-700);\n}\n\n.meta-item.status-inactive {\n color: var(--mj-text-muted);\n background: var(--mj-border-default);\n}\n\n.meta-item.status-inactive i {\n color: var(--mj-text-muted);\n}\n\n.expand-icon {\n font-size: 16px;\n color: var(--mj-text-disabled);\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 8px;\n border-radius: 8px;\n}\n\n.expand-icon:hover {\n color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.expand-icon.rotated {\n transform: rotate(180deg);\n color: var(--mj-brand-primary);\n}\n\n.card-body {\n padding: 0 24px 24px 24px;\n}\n\n.model-description {\n margin: 18px 0 0 0;\n font-size: 14px;\n line-height: 1.7;\n color: var(--mj-text-muted);\n}\n\n.model-description.text-muted {\n font-style: italic;\n color: var(--mj-text-disabled);\n}\n\n/* Expanded Content */\n.expanded-content {\n margin-top: 20px;\n padding-top: 20px;\n border-top: 1px solid var(--mj-border-default);\n animation: slideDown 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-12px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n.model-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 18px;\n}\n\n.stat-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 16px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n}\n\n.stat-label {\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.stat-value {\n font-size: 15px;\n color: var(--mj-text-primary);\n font-weight: 600;\n}\n\n/* Card Actions */\n.card-actions {\n padding: 18px 24px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n}\n\n.action-btn {\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-default);\n padding: 10px 20px;\n border-radius: 10px;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.action-btn:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n transform: translateY(-1px);\n}\n\n.action-btn-primary {\n background: var(--mj-brand-primary);\n border-color: transparent;\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.action-btn-primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n/* List View */\n.model-list {\n background: var(--mj-bg-surface);\n border-radius: 16px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n}\n\n.data-table {\n width: 100%;\n border-collapse: collapse;\n}\n\n.data-table thead {\n background: var(--mj-bg-surface-card);\n}\n\n.data-table thead tr {\n border-bottom: 2px solid var(--mj-border-default);\n}\n\n.data-table thead th {\n padding: 16px 20px;\n text-align: left;\n font-size: 12px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n cursor: pointer;\n user-select: none;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover {\n background: var(--mj-border-default);\n color: var(--mj-brand-primary);\n}\n\n.data-table thead th:last-child,\n.data-table thead th:nth-last-child(2) {\n cursor: default;\n}\n\n.data-table thead th:last-child:hover,\n.data-table thead th:nth-last-child(2):hover {\n background: transparent;\n color: var(--mj-text-secondary);\n}\n\n.data-table thead th.sorted {\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n.data-table thead th.sorted.desc .sort-icon {\n transform: rotate(180deg);\n}\n\n.data-table .sort-header {\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.data-table .sort-icon {\n font-size: 10px;\n opacity: 0;\n transition: all 0.2s ease;\n}\n\n.data-table thead th:hover .sort-icon {\n opacity: 0.5;\n}\n\n.data-table thead th.sorted .sort-icon {\n opacity: 1;\n color: var(--mj-brand-primary);\n}\n\n.data-table tbody tr {\n border-bottom: 1px solid var(--mj-bg-surface-sunken);\n transition: background-color 0.2s ease;\n}\n\n.data-table tbody tr:last-child {\n border-bottom: none;\n}\n\n.data-table tbody tr:hover {\n background: var(--mj-bg-surface-card);\n}\n\n.data-table tbody td {\n padding: 18px 20px;\n font-size: 14px;\n color: var(--mj-text-secondary);\n}\n\n.name-cell {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.name-cell i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n}\n\n/* Rank Badge */\n.rank-badge {\n display: inline-flex;\n align-items: center;\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.rank-badge.rank-high {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.rank-badge.rank-medium {\n background: color-mix(in srgb, var(--mj-status-warning) 15%, var(--mj-bg-surface));\n color: var(--mj-color-warning-700);\n}\n\n.rank-badge.rank-low {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.rank-badge.rank-none {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.status-badge.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.status-badge.inactive {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .dashboard-header {\n flex-direction: column;\n gap: 16px;\n align-items: stretch;\n padding: 16px 20px;\n }\n\n .header-info {\n flex-wrap: wrap;\n justify-content: center;\n }\n\n .header-controls {\n justify-content: center;\n }\n\n .content-area {\n padding: 16px;\n }\n\n .model-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .model-stats {\n grid-template-columns: 1fr;\n }\n\n .card-header {\n padding: 18px;\n }\n\n .card-body {\n padding: 0 18px 18px 18px;\n }\n\n .card-actions {\n padding: 14px 18px;\n flex-wrap: wrap;\n }\n}\n\n/* ============================================\n Detail Panel - Slide-in Panel\n ============================================ */\n\n/* Detail Panel Overlay */\n.detail-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n z-index: 1000;\n opacity: 0;\n animation: fadeIn 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\n}\n\n@keyframes fadeIn {\n to {\n opacity: 1;\n }\n}\n\n/* Detail Panel */\n.detail-panel {\n position: fixed;\n top: 0;\n right: -480px;\n width: 480px;\n max-width: 90vw;\n height: 100vh;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px rgba(0, 0, 0, 0.15);\n z-index: 1001;\n display: flex;\n flex-direction: column;\n transition: right 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n}\n\n.detail-panel.visible {\n right: 0;\n}\n\n/* Detail Panel Header */\n.detail-panel-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 24px;\n background: var(--mj-bg-surface-card);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.detail-panel-title {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n\n.detail-icon {\n width: 56px;\n height: 56px;\n border-radius: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n background: var(--mj-brand-primary);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.detail-icon i {\n color: var(--mj-text-inverse);\n font-size: 24px;\n}\n\n.detail-title-info h3 {\n margin: 0 0 4px 0;\n font-size: 20px;\n font-weight: 700;\n color: var(--mj-text-primary);\n}\n\n.detail-subtitle {\n font-size: 13px;\n color: var(--mj-text-muted);\n font-weight: 500;\n}\n\n.detail-panel-close {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n width: 40px;\n height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.2s ease;\n color: var(--mj-text-muted);\n}\n\n.detail-panel-close:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-border-strong);\n color: var(--mj-text-primary);\n}\n\n/* Detail Panel Content */\n.detail-panel-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n/* Detail Section */\n.detail-section {\n margin-bottom: 28px;\n}\n\n.detail-section:last-child {\n margin-bottom: 0;\n}\n\n.detail-badges {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.status-badge.status-active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.status-badge.status-inactive {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.feature-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n color: var(--mj-brand-primary-hover);\n}\n\n.feature-badge i {\n font-size: 11px;\n}\n\n.detail-description {\n margin: 0;\n font-size: 14px;\n line-height: 1.7;\n color: var(--mj-text-secondary);\n}\n\n.detail-section-title {\n display: flex;\n align-items: center;\n gap: 10px;\n margin: 0 0 16px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.detail-section-title i {\n color: var(--mj-brand-primary);\n font-size: 14px;\n}\n\n/* Detail Grid */\n.detail-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n}\n\n.detail-grid.single-column {\n grid-template-columns: 1fr;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 14px;\n background: var(--mj-bg-surface-card);\n border-radius: 12px;\n border: 1px solid var(--mj-border-default);\n}\n\n.detail-item.full-width {\n grid-column: 1 / -1;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--mj-text-primary);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.detail-value i {\n font-size: 13px;\n}\n\n.detail-value.muted {\n color: var(--mj-text-disabled);\n font-style: italic;\n}\n\n/* Status Badges in Detail Panel */\n.detail-section .status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 13px;\n font-weight: 600;\n}\n\n.detail-section .status-badge.active {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-color-success-700);\n}\n\n.detail-section .status-badge.inactive {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n/* Detail Panel Actions */\n.detail-panel-actions {\n padding: 20px 24px;\n background: var(--mj-bg-surface-card);\n border-top: 1px solid var(--mj-border-default);\n display: flex;\n gap: 12px;\n justify-content: flex-end;\n flex-shrink: 0;\n}\n\n.detail-action-btn {\n padding: 12px 24px;\n border-radius: 10px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.detail-action-btn.primary {\n background: var(--mj-brand-primary);\n border: none;\n color: var(--mj-text-inverse);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.detail-action-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-2px);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.detail-action-btn.secondary {\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.detail-action-btn.secondary:hover {\n background: var(--mj-bg-surface-card);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n/* Responsive adjustments for detail panel */\n@media (max-width: 520px) {\n .detail-panel {\n width: 100%;\n right: -100%;\n }\n\n .detail-panel.visible {\n right: 0;\n }\n\n .detail-grid {\n grid-template-columns: 1fr;\n }\n}\n\n/* Search Highlight */\n:host ::ng-deep .search-highlight,\n.search-highlight {\n background-color: color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface));\n padding: 1px 2px;\n border-radius: 2px;\n font-weight: inherit;\n}\n"] }]
|
|
1436
1436
|
}], () => [{ type: i1.SharedService }, { type: i1.NavigationService }, { type: i0.ChangeDetectorRef }], null); })();
|
|
1437
1437
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ModelManagementComponent, { className: "ModelManagementComponent", filePath: "src/AI/components/models/model-management.component.ts", lineNumber: 45 }); })();
|
|
1438
1438
|
//# sourceMappingURL=model-management.component.js.map
|