@memberjunction/ng-dashboards 5.10.1 → 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.
Files changed (231) hide show
  1. package/dist/AI/components/agents/agent-configuration.component.d.ts +34 -2
  2. package/dist/AI/components/agents/agent-configuration.component.d.ts.map +1 -1
  3. package/dist/AI/components/agents/agent-configuration.component.js +586 -223
  4. package/dist/AI/components/agents/agent-configuration.component.js.map +1 -1
  5. package/dist/AI/components/agents/agent-editor.component.js +2 -2
  6. package/dist/AI/components/agents/agent-filter-panel.component.d.ts +8 -0
  7. package/dist/AI/components/agents/agent-filter-panel.component.d.ts.map +1 -1
  8. package/dist/AI/components/agents/agent-filter-panel.component.js +85 -52
  9. package/dist/AI/components/agents/agent-filter-panel.component.js.map +1 -1
  10. package/dist/AI/components/charts/performance-heatmap.component.d.ts +1 -0
  11. package/dist/AI/components/charts/performance-heatmap.component.d.ts.map +1 -1
  12. package/dist/AI/components/charts/performance-heatmap.component.js +27 -5
  13. package/dist/AI/components/charts/performance-heatmap.component.js.map +1 -1
  14. package/dist/AI/components/charts/time-series-chart.component.d.ts +5 -0
  15. package/dist/AI/components/charts/time-series-chart.component.d.ts.map +1 -1
  16. package/dist/AI/components/charts/time-series-chart.component.js +23 -8
  17. package/dist/AI/components/charts/time-series-chart.component.js.map +1 -1
  18. package/dist/AI/components/execution-monitoring.component.js +2 -2
  19. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  20. package/dist/AI/components/models/model-management.component.js +2 -2
  21. package/dist/AI/components/prompts/model-prompt-priority-matrix.component.js +2 -2
  22. package/dist/AI/components/prompts/prompt-filter-panel.component.js +2 -2
  23. package/dist/AI/components/prompts/prompt-management.component.js +3 -3
  24. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  25. package/dist/AI/components/prompts/prompt-version-control.component.js +2 -2
  26. package/dist/AI/components/requests/agent-requests-resource.component.d.ts +83 -0
  27. package/dist/AI/components/requests/agent-requests-resource.component.d.ts.map +1 -0
  28. package/dist/AI/components/requests/agent-requests-resource.component.js +547 -0
  29. package/dist/AI/components/requests/agent-requests-resource.component.js.map +1 -0
  30. package/dist/AI/components/system/system-config-filter-panel.component.js +2 -2
  31. package/dist/AI/components/system/system-configuration.component.js +2 -2
  32. package/dist/AI/components/widgets/kpi-card.component.js +7 -7
  33. package/dist/AI/components/widgets/kpi-card.component.js.map +1 -1
  34. package/dist/AI/components/widgets/live-execution-widget.component.d.ts.map +1 -1
  35. package/dist/AI/components/widgets/live-execution-widget.component.js +6 -6
  36. package/dist/AI/components/widgets/live-execution-widget.component.js.map +1 -1
  37. package/dist/AI/index.d.ts +1 -0
  38. package/dist/AI/index.d.ts.map +1 -1
  39. package/dist/AI/index.js +2 -0
  40. package/dist/AI/index.js.map +1 -1
  41. package/dist/APIKeys/api-applications-panel.component.js +3 -3
  42. package/dist/APIKeys/api-applications-panel.component.js.map +1 -1
  43. package/dist/APIKeys/api-key-create-dialog.component.js +3 -3
  44. package/dist/APIKeys/api-key-create-dialog.component.js.map +1 -1
  45. package/dist/APIKeys/api-key-edit-panel.component.js +1 -1
  46. package/dist/APIKeys/api-key-edit-panel.component.js.map +1 -1
  47. package/dist/APIKeys/api-key-list.component.js +3 -3
  48. package/dist/APIKeys/api-key-list.component.js.map +1 -1
  49. package/dist/APIKeys/api-keys-resource.component.js +1 -1
  50. package/dist/APIKeys/api-keys-resource.component.js.map +1 -1
  51. package/dist/APIKeys/api-scopes-panel.component.js +2 -2
  52. package/dist/APIKeys/api-usage-panel.component.js +2 -2
  53. package/dist/Actions/components/actions-overview.component.js +2 -2
  54. package/dist/Actions/components/execution-monitoring.component.js +2 -2
  55. package/dist/Actions/components/explorer/action-breadcrumb.component.js +2 -2
  56. package/dist/Actions/components/explorer/action-card.component.js +2 -2
  57. package/dist/Actions/components/explorer/action-explorer.component.js +2 -2
  58. package/dist/Actions/components/explorer/action-list-item.component.js +2 -2
  59. package/dist/Actions/components/explorer/action-toolbar.component.js +2 -2
  60. package/dist/Actions/components/explorer/action-tree-panel.component.js +2 -2
  61. package/dist/Actions/components/explorer/new-action-panel.component.js +2 -2
  62. package/dist/Actions/components/explorer/new-action-panel.component.js.map +1 -1
  63. package/dist/Actions/components/explorer/new-category-panel.component.js +2 -2
  64. package/dist/Actions/components/explorer/new-category-panel.component.js.map +1 -1
  65. package/dist/Communication/communication-dashboard.component.js +2 -2
  66. package/dist/Communication/communication-logs-resource.component.d.ts.map +1 -1
  67. package/dist/Communication/communication-logs-resource.component.js +3 -3
  68. package/dist/Communication/communication-logs-resource.component.js.map +1 -1
  69. package/dist/Communication/communication-monitor-resource.component.d.ts.map +1 -1
  70. package/dist/Communication/communication-monitor-resource.component.js +5 -5
  71. package/dist/Communication/communication-monitor-resource.component.js.map +1 -1
  72. package/dist/Communication/communication-providers-resource.component.d.ts.map +1 -1
  73. package/dist/Communication/communication-providers-resource.component.js +3 -3
  74. package/dist/Communication/communication-providers-resource.component.js.map +1 -1
  75. package/dist/Communication/communication-runs-resource.component.d.ts.map +1 -1
  76. package/dist/Communication/communication-runs-resource.component.js +3 -3
  77. package/dist/Communication/communication-runs-resource.component.js.map +1 -1
  78. package/dist/Communication/communication-templates-resource.component.js +2 -2
  79. package/dist/Communication/communication-templates-resource.component.js.map +1 -1
  80. package/dist/ComponentStudio/component-studio-dashboard.component.js +2 -2
  81. package/dist/ComponentStudio/components/ai-assistant/ai-assistant-panel.component.js +2 -2
  82. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +2 -2
  83. package/dist/ComponentStudio/components/artifact-selection-dialog.component.js +2 -2
  84. package/dist/ComponentStudio/components/browser/component-browser.component.js +2 -2
  85. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js +2 -2
  86. package/dist/ComponentStudio/components/editors/code-editor-panel.component.js.map +1 -1
  87. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js +2 -2
  88. package/dist/ComponentStudio/components/editors/data-requirements-editor.component.js.map +1 -1
  89. package/dist/ComponentStudio/components/editors/requirements-editor.component.js +2 -2
  90. package/dist/ComponentStudio/components/editors/requirements-editor.component.js.map +1 -1
  91. package/dist/ComponentStudio/components/editors/spec-editor.component.js +2 -2
  92. package/dist/ComponentStudio/components/editors/spec-editor.component.js.map +1 -1
  93. package/dist/ComponentStudio/components/new-component-dialog/new-component-dialog.component.js +2 -2
  94. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js +2 -2
  95. package/dist/ComponentStudio/components/save-version-dialog/save-version-dialog.component.js.map +1 -1
  96. package/dist/ComponentStudio/components/text-import-dialog.component.js +2 -2
  97. package/dist/ComponentStudio/components/text-import-dialog.component.js.map +1 -1
  98. package/dist/ComponentStudio/components/workspace/component-preview.component.js +2 -2
  99. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js +2 -2
  100. package/dist/ComponentStudio/components/workspace/editor-tabs.component.js.map +1 -1
  101. package/dist/Credentials/components/credentials-audit-resource.component.js +9 -9
  102. package/dist/Credentials/components/credentials-audit-resource.component.js.map +1 -1
  103. package/dist/Credentials/components/credentials-categories-resource.component.d.ts.map +1 -1
  104. package/dist/Credentials/components/credentials-categories-resource.component.js +11 -3
  105. package/dist/Credentials/components/credentials-categories-resource.component.js.map +1 -1
  106. package/dist/Credentials/components/credentials-list-resource.component.js +2 -2
  107. package/dist/Credentials/components/credentials-overview-resource.component.d.ts.map +1 -1
  108. package/dist/Credentials/components/credentials-overview-resource.component.js +12 -11
  109. package/dist/Credentials/components/credentials-overview-resource.component.js.map +1 -1
  110. package/dist/Credentials/components/credentials-types-resource.component.js +9 -9
  111. package/dist/Credentials/components/credentials-types-resource.component.js.map +1 -1
  112. package/dist/Credentials/credentials-dashboard.component.js +2 -2
  113. package/dist/DashboardBrowser/dashboard-browser-resource.component.js +2 -2
  114. package/dist/DashboardBrowser/dashboard-share-dialog.component.js +2 -2
  115. package/dist/DataExplorer/components/filter-dialog/filter-dialog.component.js +2 -2
  116. package/dist/DataExplorer/components/navigation-panel/navigation-panel.component.js +2 -2
  117. package/dist/DataExplorer/components/view-selector/view-selector.component.js +2 -2
  118. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +6 -2
  119. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  120. package/dist/DataExplorer/data-explorer-dashboard.component.js +26 -8
  121. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  122. package/dist/Home/home-dashboard.component.js +2 -2
  123. package/dist/Integration/components/activity/activity.component.d.ts +1 -1
  124. package/dist/Integration/components/activity/activity.component.d.ts.map +1 -1
  125. package/dist/Integration/components/activity/activity.component.js +5 -5
  126. package/dist/Integration/components/activity/activity.component.js.map +1 -1
  127. package/dist/Integration/components/connections/connections.component.d.ts +31 -2
  128. package/dist/Integration/components/connections/connections.component.d.ts.map +1 -1
  129. package/dist/Integration/components/connections/connections.component.js +753 -412
  130. package/dist/Integration/components/connections/connections.component.js.map +1 -1
  131. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js +3 -3
  132. package/dist/Integration/components/mapping-workspace/mapping-workspace.component.js.map +1 -1
  133. package/dist/Integration/components/overview/overview.component.d.ts +0 -1
  134. package/dist/Integration/components/overview/overview.component.d.ts.map +1 -1
  135. package/dist/Integration/components/overview/overview.component.js +3 -6
  136. package/dist/Integration/components/overview/overview.component.js.map +1 -1
  137. package/dist/Integration/components/pipelines/pipelines.component.js +3 -3
  138. package/dist/Integration/components/pipelines/pipelines.component.js.map +1 -1
  139. package/dist/Integration/components/schedules/schedules.component.d.ts +20 -0
  140. package/dist/Integration/components/schedules/schedules.component.d.ts.map +1 -1
  141. package/dist/Integration/components/schedules/schedules.component.js +97 -5
  142. package/dist/Integration/components/schedules/schedules.component.js.map +1 -1
  143. package/dist/Integration/components/visual-editor/visual-editor.component.js +2 -2
  144. package/dist/Integration/components/widgets/integration-card.component.d.ts.map +1 -1
  145. package/dist/Integration/components/widgets/integration-card.component.js +5 -1
  146. package/dist/Integration/components/widgets/integration-card.component.js.map +1 -1
  147. package/dist/Integration/components/widgets/run-history-panel.component.js +2 -2
  148. package/dist/Integration/components/widgets/run-history-panel.component.js.map +1 -1
  149. package/dist/Integration/integration.module.d.ts +2 -1
  150. package/dist/Integration/integration.module.d.ts.map +1 -1
  151. package/dist/Integration/integration.module.js +7 -3
  152. package/dist/Integration/integration.module.js.map +1 -1
  153. package/dist/Integration/services/integration-data.service.d.ts +27 -2
  154. package/dist/Integration/services/integration-data.service.d.ts.map +1 -1
  155. package/dist/Integration/services/integration-data.service.js +107 -4
  156. package/dist/Integration/services/integration-data.service.js.map +1 -1
  157. package/dist/Lists/components/lists-browse-resource.component.js +2 -2
  158. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  159. package/dist/Lists/components/lists-categories-resource.component.js +2 -2
  160. package/dist/Lists/components/lists-categories-resource.component.js.map +1 -1
  161. package/dist/Lists/components/lists-my-lists-resource.component.js +2 -2
  162. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  163. package/dist/Lists/components/lists-operations-resource.component.js +2 -2
  164. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  165. package/dist/Lists/components/venn-diagram/venn-diagram.component.js +3 -3
  166. package/dist/Lists/components/venn-diagram/venn-diagram.component.js.map +1 -1
  167. package/dist/MCP/components/mcp-connection-dialog.component.js +2 -2
  168. package/dist/MCP/components/mcp-log-detail-panel.component.js +2 -2
  169. package/dist/MCP/components/mcp-log-detail-panel.component.js.map +1 -1
  170. package/dist/MCP/components/mcp-server-dialog.component.js +2 -2
  171. package/dist/MCP/components/mcp-test-tool-dialog.component.js +2 -2
  172. package/dist/MCP/components/mcp-test-tool-dialog.component.js.map +1 -1
  173. package/dist/MCP/mcp-dashboard.component.js +2 -2
  174. package/dist/MCP/mcp-filter-panel.component.js +2 -2
  175. package/dist/QueryBrowser/query-browser-resource.component.d.ts +55 -1
  176. package/dist/QueryBrowser/query-browser-resource.component.d.ts.map +1 -1
  177. package/dist/QueryBrowser/query-browser-resource.component.js +664 -199
  178. package/dist/QueryBrowser/query-browser-resource.component.js.map +1 -1
  179. package/dist/Scheduling/components/index.d.ts +0 -1
  180. package/dist/Scheduling/components/index.d.ts.map +1 -1
  181. package/dist/Scheduling/components/index.js +0 -1
  182. package/dist/Scheduling/components/index.js.map +1 -1
  183. package/dist/Scheduling/components/scheduling-activity.component.js +2 -2
  184. package/dist/Scheduling/components/scheduling-jobs.component.d.ts +6 -9
  185. package/dist/Scheduling/components/scheduling-jobs.component.d.ts.map +1 -1
  186. package/dist/Scheduling/components/scheduling-jobs.component.js +118 -110
  187. package/dist/Scheduling/components/scheduling-jobs.component.js.map +1 -1
  188. package/dist/Scheduling/components/scheduling-overview.component.js +3 -3
  189. package/dist/Scheduling/components/scheduling-overview.component.js.map +1 -1
  190. package/dist/Scheduling/scheduling-dashboard.component.js +2 -2
  191. package/dist/SystemDiagnostics/system-diagnostics.component.js +4 -4
  192. package/dist/SystemDiagnostics/system-diagnostics.component.js.map +1 -1
  193. package/dist/Testing/components/testing-analytics.component.js +2 -2
  194. package/dist/Testing/components/testing-analytics.component.js.map +1 -1
  195. package/dist/Testing/components/testing-dashboard-tab.component.js +4 -4
  196. package/dist/Testing/components/testing-dashboard-tab.component.js.map +1 -1
  197. package/dist/Testing/components/testing-explorer.component.js +2 -2
  198. package/dist/Testing/components/testing-explorer.component.js.map +1 -1
  199. package/dist/Testing/components/testing-review.component.d.ts.map +1 -1
  200. package/dist/Testing/components/testing-review.component.js +5 -5
  201. package/dist/Testing/components/testing-review.component.js.map +1 -1
  202. package/dist/Testing/components/testing-runs.component.js +2 -2
  203. package/dist/Testing/components/testing-runs.component.js.map +1 -1
  204. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js +2 -2
  205. package/dist/Testing/components/widgets/oracle-breakdown-table.component.js.map +1 -1
  206. package/dist/Testing/components/widgets/suite-tree.component.js +4 -4
  207. package/dist/Testing/components/widgets/suite-tree.component.js.map +1 -1
  208. package/dist/Testing/components/widgets/test-run-detail-panel.component.js +2 -2
  209. package/dist/Testing/components/widgets/test-run-detail-panel.component.js.map +1 -1
  210. package/dist/Testing/testing-dashboard.component.js +2 -2
  211. package/dist/VersionHistory/components/diff-resource.component.js +2 -2
  212. package/dist/VersionHistory/components/graph-resource.component.js +2 -2
  213. package/dist/VersionHistory/components/labels-resource.component.js +3 -3
  214. package/dist/VersionHistory/components/labels-resource.component.js.map +1 -1
  215. package/dist/VersionHistory/components/restore-resource.component.js +3 -3
  216. package/dist/VersionHistory/components/restore-resource.component.js.map +1 -1
  217. package/dist/__tests__/integration-data-service.test.js +1 -0
  218. package/dist/__tests__/integration-data-service.test.js.map +1 -1
  219. package/dist/module.d.ts +52 -49
  220. package/dist/module.d.ts.map +1 -1
  221. package/dist/module.js +25 -6
  222. package/dist/module.js.map +1 -1
  223. package/dist/public-api.d.ts +1 -1
  224. package/dist/public-api.d.ts.map +1 -1
  225. package/dist/public-api.js +1 -1
  226. package/dist/public-api.js.map +1 -1
  227. package/package.json +42 -40
  228. package/dist/Scheduling/components/job-slideout.component.d.ts +0 -45
  229. package/dist/Scheduling/components/job-slideout.component.d.ts.map +0 -1
  230. package/dist/Scheduling/components/job-slideout.component.js +0 -459
  231. package/dist/Scheduling/components/job-slideout.component.js.map +0 -1
@@ -446,7 +446,7 @@ export class APIApplicationsPanelComponent {
446
446
  // Default UI config for categories without explicit configuration
447
447
  defaultUIConfig = {
448
448
  icon: 'fa-solid fa-ellipsis',
449
- color: '#6b7280'
449
+ color: 'var(--mj-text-muted)'
450
450
  };
451
451
  constructor(cdr) {
452
452
  this.cdr = cdr;
@@ -1045,11 +1045,11 @@ export class APIApplicationsPanelComponent {
1045
1045
  i0.ɵɵconditional(ctx.IsSaving ? 61 : -1);
1046
1046
  i0.ɵɵadvance();
1047
1047
  i0.ɵɵconditional(!ctx.IsSaving ? 62 : -1);
1048
- } }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.DropDownListComponent, i4.TextBoxDirective, i4.TextAreaDirective, i4.CheckBoxDirective, i5.ButtonComponent, i6.LoadingComponent], styles: [".applications-panel[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.applications-panel.panel-open[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-violet-500);\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.btn-create[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-create[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-color-violet-500) 40%, transparent); \n\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 14px;\n}\n\n.message.success[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.message.error[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n border: 1px solid var(--mj-status-error-border);\n}\n\n\n\n.applications-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.app-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n overflow: hidden;\n transition: box-shadow 0.2s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-lg);\n}\n\n.app-card.inactive[_ngcontent-%COMP%] {\n opacity: 0.7;\n}\n\n.app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.app-header-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex: 1;\n cursor: pointer;\n transition: background 0.2s ease;\n border-radius: 8px;\n padding: 4px;\n margin: -4px;\n}\n\n.app-header-main[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.app-edit-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.app-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-color-violet-500);\n border-color: var(--mj-color-violet-500);\n color: var(--mj-text-inverse);\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n border-radius: 10px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.status-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-badge.active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.inactive[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: 16px;\n}\n\n.scope-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scope-count[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-violet-500);\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n\n\n.app-details[_ngcontent-%COMP%] {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: 0;\n}\n\n.details-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.details-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 12px 0;\n}\n\n.scope-rules[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-rule[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 10px 12px;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.rule-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.rule-icon.pattern-include[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.rule-icon.pattern-exclude[_ngcontent-%COMP%] {\n background: var(--mj-color-brand-100);\n color: var(--mj-brand-primary-hover);\n}\n\n.rule-icon.pattern-deny[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.rule-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.rule-scope[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.rule-pattern[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n.rule-pattern[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: monospace;\n font-size: 12px;\n background: var(--mj-bg-surface-active);\n padding: 2px 6px;\n border-radius: 4px;\n color: var(--mj-text-primary);\n}\n\n.pattern-type[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.priority[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-color-violet-500);\n}\n\n.empty-scopes[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px;\n color: var(--mj-text-secondary);\n text-align: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.empty-scopes[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-top: 8px;\n}\n\n\n\n\n\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 100;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n width: 570px;\n height: 100%;\n max-height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n transform: translateX(100%);\n}\n\n.slideout-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n\n\n.slideout-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 6px;\n height: 100%;\n cursor: ew-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s ease;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover, \n.slideout-resize-handle.resizing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-color-violet-500) 30%, transparent);\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 40px;\n background: var(--mj-color-neutral-300);\n border-radius: 2px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover::after {\n opacity: 1;\n}\n\n\n\n.slideout-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-violet-500);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-of-type {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.status-pill[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n padding: 3px 10px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.status-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.slideout-close[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-color-neutral-700);\n}\n\n\n\n.slideout-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\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.2s ease;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-color-neutral-700);\n}\n\n.slideout-tab.active[_ngcontent-%COMP%] {\n background: var(--mj-color-violet-500);\n color: var(--mj-text-inverse);\n}\n\n.slideout-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:not(.active) .tab-badge[_ngcontent-%COMP%] {\n background: var(--mj-border-default); \n\n color: var(--mj-color-neutral-700);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.tab-panel[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.scopes-panel[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-field[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 0;\n}\n\n.form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-color-neutral-700);\n margin-bottom: 8px;\n letter-spacing: 0.01em;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n resize: vertical;\n min-height: 80px;\n}\n\n[_nghost-%COMP%] .form-input .k-input, \n[_nghost-%COMP%] .form-textarea .k-input-inner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .form-input:focus-within, \n[_nghost-%COMP%] .form-textarea:focus-within {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-color-violet-500) 10%, transparent); \n\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default); \n\n flex-shrink: 0;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary {\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n border: none;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-color-violet-500) 30%, transparent);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-color-violet-500) 40%, transparent);\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.checkbox-label[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-300);\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.checkbox-label[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-of-type {\n font-weight: 600;\n color: var(--mj-color-neutral-700);\n font-size: 14px;\n}\n\n.checkbox-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n line-height: 1.4;\n}\n\n\n\n\n\n\n\n\n\n.scopes-intro[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border: 1px solid var(--mj-status-info-border);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n margin-bottom: 16px;\n line-height: 1.4;\n}\n\n.scopes-intro[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.scope-categories-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.category-count-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.category-all-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-chevron[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.category-scopes-list[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default); \n\n padding: 8px;\n max-height: 280px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.scope-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-page);\n transition: all 0.2s ease;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.scope-row.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-violet-100);\n border: 1px solid var(--mj-color-violet-300);\n}\n\n.scope-select[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n flex: 1;\n min-width: 0;\n cursor: pointer;\n}\n\n.scope-select[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.scope-label[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.scope-path[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-primary);\n font-family: 'SF Mono', 'Consolas', monospace;\n word-break: break-word;\n}\n\n.scope-description[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.scope-pattern-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: 'SF Mono', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-color-neutral-700);\n}\n\n.pattern-tag.include[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.pattern-tag.exclude[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n}\n\n.pattern-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.scope-pattern-config[_ngcontent-%COMP%] {\n display: none;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover .scope-pattern-config[_ngcontent-%COMP%], \n.scope-row.editing[_ngcontent-%COMP%] .scope-pattern-config[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover .scope-pattern-display[_ngcontent-%COMP%], \n.scope-row.editing[_ngcontent-%COMP%] .scope-pattern-display[_ngcontent-%COMP%] {\n display: none;\n}\n\n.pattern-field[_ngcontent-%COMP%] {\n width: 60px;\n}\n\n[_nghost-%COMP%] .pattern-field .k-input {\n padding: 3px 6px;\n font-size: 11px;\n border-radius: 4px;\n height: 26px;\n}\n\n.type-field[_ngcontent-%COMP%] {\n width: 75px;\n}\n\n[_nghost-%COMP%] .type-field .k-dropdownlist {\n font-size: 11px;\n height: 26px;\n}\n\n[_nghost-%COMP%] .type-field .k-input-inner {\n padding: 2px 6px;\n font-size: 11px;\n}\n\n.empty-scopes-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.empty-scopes-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n"] });
1048
+ } }, dependencies: [i1.NgClass, i2.DefaultValueAccessor, i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.DropDownListComponent, i4.TextBoxDirective, i4.TextAreaDirective, i4.CheckBoxDirective, i5.ButtonComponent, i6.LoadingComponent], styles: [".applications-panel[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.applications-panel.panel-open[_ngcontent-%COMP%] {\n overflow: hidden;\n}\n\n\n\n.panel-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.panel-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.panel-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.panel-subtitle[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.btn-create[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-create[_ngcontent-%COMP%]:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n\n\n.message[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 14px;\n}\n\n.message.success[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.message.error[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error-border);\n}\n\n\n\n.applications-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.app-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n overflow: hidden;\n transition: box-shadow 0.2s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-lg);\n}\n\n.app-card.inactive[_ngcontent-%COMP%] {\n opacity: 0.7;\n}\n\n.app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.app-header-main[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n flex: 1;\n cursor: pointer;\n transition: background 0.2s ease;\n border-radius: 8px;\n padding: 4px;\n margin: -4px;\n}\n\n.app-header-main[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.app-edit-btn[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.app-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 10px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.status-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-badge.active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.inactive[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-stats[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: 16px;\n}\n\n.scope-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scope-count[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.expand-icon[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n\n\n.app-details[_ngcontent-%COMP%] {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: 0;\n}\n\n.details-section[_ngcontent-%COMP%] {\n margin-top: 16px;\n}\n\n.details-section[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 12px 0;\n}\n\n.scope-rules[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-rule[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n padding: 10px 12px;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.rule-icon[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.rule-icon.pattern-include[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.rule-icon.pattern-exclude[_ngcontent-%COMP%] {\n background: var(--mj-color-brand-100);\n color: var(--mj-brand-primary-hover);\n}\n\n.rule-icon.pattern-deny[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.rule-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.rule-scope[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.rule-pattern[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n.rule-pattern[_ngcontent-%COMP%] code[_ngcontent-%COMP%] {\n font-family: monospace;\n font-size: 12px;\n background: var(--mj-bg-surface-active);\n padding: 2px 6px;\n border-radius: 4px;\n color: var(--mj-text-primary);\n}\n\n.pattern-type[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.priority[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.empty-scopes[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px;\n color: var(--mj-text-secondary);\n text-align: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.empty-scopes[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 500;\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 14px;\n margin-top: 8px;\n}\n\n\n\n\n\n\n\n\n.slideout-backdrop[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 100;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n\n.slideout-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n width: 570px;\n height: 100%;\n max-height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n transform: translateX(100%);\n}\n\n.slideout-panel.open[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n\n\n.slideout-resize-handle[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n width: 6px;\n height: 100%;\n cursor: ew-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s ease;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover, \n.slideout-resize-handle.resizing[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 40px;\n background: var(--mj-color-neutral-300);\n border-radius: 2px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.slideout-resize-handle[_ngcontent-%COMP%]:hover::after {\n opacity: 1;\n}\n\n\n\n.slideout-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-title[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-of-type {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.status-pill[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 500;\n padding: 3px 10px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.status-pill.active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.slideout-close[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n\n\n.slideout-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\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.2s ease;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.slideout-tab.active[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.slideout-tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.slideout-tab[_ngcontent-%COMP%]:not(.active) .tab-badge[_ngcontent-%COMP%] {\n background: var(--mj-border-default); \n\n color: var(--mj-text-secondary);\n}\n\n\n\n.slideout-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.tab-panel[_ngcontent-%COMP%] {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.scopes-panel[_ngcontent-%COMP%] {\n height: 100%;\n}\n\n\n\n.form-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.form-field[_ngcontent-%COMP%]:last-of-type {\n margin-bottom: 0;\n}\n\n.form-field[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n letter-spacing: 0.01em;\n}\n\n.form-input[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.form-textarea[_ngcontent-%COMP%] {\n width: 100%;\n resize: vertical;\n min-height: 80px;\n}\n\n[_nghost-%COMP%] .form-input .k-input, \n[_nghost-%COMP%] .form-textarea .k-input-inner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .form-input:focus-within, \n[_nghost-%COMP%] .form-textarea:focus-within {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n\n\n.slideout-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default); \n\n flex-shrink: 0;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n[_nghost-%COMP%] .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.checkbox-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.checkbox-label[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-300);\n}\n\n.checkbox-label[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.checkbox-label[_ngcontent-%COMP%] span[_ngcontent-%COMP%]:first-of-type {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.checkbox-hint[_ngcontent-%COMP%] {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n line-height: 1.4;\n}\n\n\n\n\n\n\n\n\n\n.scopes-intro[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border: 1px solid var(--mj-status-info-border);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n margin-bottom: 16px;\n line-height: 1.4;\n}\n\n.scopes-intro[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-info);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.scope-categories-list[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-page);\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-left[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-left[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-name[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.category-count-badge[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.scope-category-card[_ngcontent-%COMP%] .category-right[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.category-all-toggle[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-chevron[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.category-scopes-list[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-default); \n\n padding: 8px;\n max-height: 280px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.scope-row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-page);\n transition: all 0.2s ease;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.scope-row.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-violet-100);\n border: 1px solid var(--mj-color-violet-300);\n}\n\n.scope-select[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n flex: 1;\n min-width: 0;\n cursor: pointer;\n}\n\n.scope-select[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.scope-label[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.scope-path[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-primary);\n font-family: 'SF Mono', 'Consolas', monospace;\n word-break: break-word;\n}\n\n.scope-description[_ngcontent-%COMP%] {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.scope-pattern-display[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: 'SF Mono', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag.include[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.pattern-tag.exclude[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.pattern-tag[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n.scope-pattern-config[_ngcontent-%COMP%] {\n display: none;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover .scope-pattern-config[_ngcontent-%COMP%], \n.scope-row.editing[_ngcontent-%COMP%] .scope-pattern-config[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.scope-row[_ngcontent-%COMP%]:hover .scope-pattern-display[_ngcontent-%COMP%], \n.scope-row.editing[_ngcontent-%COMP%] .scope-pattern-display[_ngcontent-%COMP%] {\n display: none;\n}\n\n.pattern-field[_ngcontent-%COMP%] {\n width: 60px;\n}\n\n[_nghost-%COMP%] .pattern-field .k-input {\n padding: 3px 6px;\n font-size: 11px;\n border-radius: 4px;\n height: 26px;\n}\n\n.type-field[_ngcontent-%COMP%] {\n width: 75px;\n}\n\n[_nghost-%COMP%] .type-field .k-dropdownlist {\n font-size: 11px;\n height: 26px;\n}\n\n[_nghost-%COMP%] .type-field .k-input-inner {\n padding: 2px 6px;\n font-size: 11px;\n}\n\n.empty-scopes-message[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.empty-scopes-message[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n\n"] });
1049
1049
  }
1050
1050
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(APIApplicationsPanelComponent, [{
1051
1051
  type: Component,
1052
- args: [{ standalone: false, selector: 'mj-api-applications-panel', template: "<div class=\"applications-panel\" [class.panel-open]=\"ShowEditPanel || ShowCreatePanel\">\n @if (IsLoading) {\n <mj-loading text=\"Loading applications...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-left\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-cube\"></i>\n API Applications\n </h3>\n <p class=\"panel-subtitle\">Manage applications and their default scope permissions</p>\n </div>\n <button class=\"btn-create\" (click)=\"openCreatePanel()\">\n <i class=\"fa-solid fa-plus\"></i>\n New Application\n </button>\n </div>\n <!-- Messages -->\n @if (SuccessMessage) {\n <div class=\"message success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n {{SuccessMessage}}\n </div>\n }\n @if (ErrorMessage) {\n <div class=\"message error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ErrorMessage}}\n </div>\n }\n <!-- Applications Grid -->\n <div class=\"applications-grid\">\n @for (appItem of Applications; track appItem) {\n <div class=\"app-card\"\n [class.inactive]=\"!appItem.application.IsActive\"\n [class.expanded]=\"appItem.expanded\">\n <div class=\"app-header\">\n <div class=\"app-header-main\" (click)=\"toggleExpanded(appItem)\">\n <div class=\"app-icon\">\n <i class=\"fa-solid fa-cube\"></i>\n </div>\n <div class=\"app-info\">\n <div class=\"app-name\">\n {{appItem.application.Name}}\n <span class=\"status-badge\" [class.active]=\"appItem.application.IsActive\"\n [class.inactive]=\"!appItem.application.IsActive\">\n {{appItem.application.IsActive ? 'Active' : 'Inactive'}}\n </span>\n </div>\n @if (appItem.application.Description) {\n <div class=\"app-description\">\n {{appItem.application.Description}}\n </div>\n }\n </div>\n <div class=\"app-stats\">\n <div class=\"scope-count\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n {{appItem.scopeCount}} scopes\n </div>\n <i class=\"fa-solid expand-icon\"\n [class.fa-chevron-down]=\"!appItem.expanded\"\n [class.fa-chevron-up]=\"appItem.expanded\"></i>\n </div>\n </div>\n <button class=\"app-edit-btn\" (click)=\"openEditPanel(appItem); $event.stopPropagation()\" title=\"Edit Application\">\n <i class=\"fa-solid fa-pencil\"></i>\n </button>\n </div>\n <!-- Expanded Content -->\n @if (appItem.expanded) {\n <div class=\"app-details\">\n <div class=\"details-section\">\n <h4>Scope Ceiling Rules</h4>\n @if (appItem.scopes.length > 0) {\n <div class=\"scope-rules\">\n @for (scope of appItem.scopes; track scope) {\n <div class=\"scope-rule\">\n <div class=\"rule-icon\" [ngClass]=\"getPatternClass(scope.PatternType, scope.IsDeny)\">\n <i [class]=\"getPatternIcon(scope.PatternType, scope.IsDeny)\"></i>\n </div>\n <div class=\"rule-info\">\n <div class=\"rule-scope\">{{getScopeName(scope.ScopeID)}}</div>\n <div class=\"rule-pattern\">\n <code>{{scope.ResourcePattern}}</code>\n <span class=\"pattern-type\">{{scope.PatternType}}</span>\n @if (scope.Priority > 0) {\n <span class=\"priority\">\n Priority: {{scope.Priority}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (appItem.scopes.length === 0) {\n <div class=\"empty-scopes\">\n <i class=\"fa-solid fa-shield-xmark\"></i>\n <span>No scope rules defined - all access denied by default</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (Applications.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-cube\"></i>\n <span>No applications configured</span>\n <p>Create an application to define scope ceilings for API key access</p>\n </div>\n }\n </div>\n }\n\n <!-- Slide-out Backdrop -->\n @if (ShowEditPanel || ShowCreatePanel) {\n <div class=\"slideout-backdrop\" (click)=\"closePanel()\"></div>\n }\n\n <!-- Create Panel (Slide-out) -->\n <div class=\"slideout-panel\" [class.open]=\"ShowCreatePanel\">\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-plus-circle\"></i>\n <span>New Application</span>\n </div>\n <button class=\"slideout-close\" (click)=\"closePanel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <div class=\"form-section\">\n <div class=\"form-field\">\n <label>Application Name *</label>\n <input kendoTextBox [(ngModel)]=\"EditName\"\n placeholder=\"e.g., MJAPI, MCP Server, Portal\"\n class=\"form-input\" />\n </div>\n\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n placeholder=\"Describe the application's purpose...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox [(ngModel)]=\"EditIsActive\" />\n <div>\n <span>Active</span>\n <span class=\"checkbox-hint\">Inactive applications cannot be used with API keys</span>\n </div>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-footer\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"!EditName.trim() || IsSaving\"\n (click)=\"saveApplication()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Create Application\n </span>\n }\n </button>\n <button kendoButton (click)=\"closePanel()\">Cancel</button>\n </div>\n </div>\n\n <!-- Edit Panel (Slide-out) -->\n <div class=\"slideout-panel\" [class.open]=\"ShowEditPanel\" [style.width.px]=\"PanelWidth\">\n <!-- Resize Handle -->\n <div class=\"slideout-resize-handle\"\n [class.resizing]=\"IsResizing\"\n (mousedown)=\"startResize($event)\"></div>\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-cube\"></i>\n <span>{{EditingApplication?.Name}}</span>\n <span class=\"status-pill\" [class.active]=\"EditIsActive\">\n {{EditIsActive ? 'Active' : 'Inactive'}}\n </span>\n </div>\n <button class=\"slideout-close\" (click)=\"closePanel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Bar -->\n <div class=\"slideout-tabs\">\n <button class=\"slideout-tab\" [class.active]=\"EditTab === 'details'\"\n (click)=\"EditTab = 'details'\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Details\n </button>\n <button class=\"slideout-tab\" [class.active]=\"EditTab === 'scopes'\"\n (click)=\"EditTab = 'scopes'\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Scopes\n <span class=\"tab-badge\">{{getSelectedScopeCount()}}</span>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <!-- Details Tab -->\n @if (EditTab === 'details') {\n <div class=\"tab-panel\">\n <div class=\"form-section\">\n <div class=\"form-field\">\n <label>Application Name *</label>\n <input kendoTextBox [(ngModel)]=\"EditName\"\n placeholder=\"e.g., MJAPI, MCP Server, Portal\"\n class=\"form-input\" />\n </div>\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n placeholder=\"Describe the application's purpose...\"\n [rows]=\"4\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-field\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox [(ngModel)]=\"EditIsActive\" />\n <div>\n <span>Active</span>\n <span class=\"checkbox-hint\">Inactive applications cannot be used with API keys</span>\n </div>\n </label>\n </div>\n </div>\n </div>\n }\n\n <!-- Scopes Tab -->\n @if (EditTab === 'scopes') {\n <div class=\"tab-panel scopes-panel\">\n <div class=\"scopes-intro\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Define the maximum permissions this application can grant to API keys.</span>\n </div>\n <div class=\"scope-categories-list\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category-card\">\n <div class=\"category-header\" (click)=\"toggleScopeCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-count-badge\">\n {{getCategorySelectedCount(category)}}/{{category.scopes.length}}\n </span>\n </div>\n <div class=\"category-right\">\n <label class=\"category-all-toggle\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid category-chevron\"\n [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes-list\">\n @for (selection of category.scopes; track selection) {\n <div class=\"scope-row\"\n [class.selected]=\"selection.selected\">\n <label class=\"scope-select\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"selection.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-label\">\n <span class=\"scope-path\">{{selection.displayName || '(unnamed scope)'}}</span>\n @if (selection.scope.Description) {\n <span class=\"scope-description\">\n {{selection.scope.Description}}\n </span>\n }\n </div>\n </label>\n <!-- Read-only pattern display -->\n @if (selection.selected) {\n <div class=\"scope-pattern-display\">\n <span class=\"pattern-tag\" [class.include]=\"selection.patternType === 'Include'\"\n [class.exclude]=\"selection.patternType === 'Exclude'\">\n <i class=\"fa-solid\" [class.fa-check]=\"selection.patternType === 'Include'\"\n [class.fa-minus]=\"selection.patternType === 'Exclude'\"></i>\n {{selection.pattern || '*'}}\n </span>\n </div>\n }\n <!-- Editable pattern config - shown on hover -->\n @if (selection.selected) {\n <div class=\"scope-pattern-config\">\n <input kendoTextBox [(ngModel)]=\"selection.pattern\"\n placeholder=\"*\"\n class=\"pattern-field\"\n title=\"Resource Pattern\" />\n <kendo-dropdownlist [(ngModel)]=\"selection.patternType\"\n [data]=\"['Include', 'Exclude']\"\n [valuePrimitive]=\"true\"\n class=\"type-field\"\n title=\"Pattern Type\">\n </kendo-dropdownlist>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (ScopeCategories.length === 0) {\n <div class=\"empty-scopes-message\">\n <i class=\"fa-solid fa-shield-xmark\"></i>\n <span>No scopes available</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <div class=\"slideout-footer\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"!EditName.trim() || IsSaving\"\n (click)=\"saveAll()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n <button kendoButton (click)=\"closePanel()\">Cancel</button>\n </div>\n </div>\n</div>\n", styles: [".applications-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.applications-panel.panel-open {\n overflow: hidden;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.panel-title i {\n color: var(--mj-color-violet-500);\n}\n\n.panel-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.btn-create {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-create:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-color-violet-500) 40%, transparent); /* violet shadow for create button */\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 14px;\n}\n\n.message.success {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.message.error {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n border: 1px solid var(--mj-status-error-border);\n}\n\n/* Applications Grid */\n.applications-grid {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.app-card {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n overflow: hidden;\n transition: box-shadow 0.2s ease;\n}\n\n.app-card:hover {\n box-shadow: var(--mj-shadow-lg);\n}\n\n.app-card.inactive {\n opacity: 0.7;\n}\n\n.app-header {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.app-header-main {\n display: flex;\n align-items: center;\n flex: 1;\n cursor: pointer;\n transition: background 0.2s ease;\n border-radius: 8px;\n padding: 4px;\n margin: -4px;\n}\n\n.app-header-main:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.app-edit-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.app-edit-btn:hover {\n background: var(--mj-color-violet-500);\n border-color: var(--mj-color-violet-500);\n color: var(--mj-text-inverse);\n}\n\n.app-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n border-radius: 10px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.app-icon i {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.status-badge {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-badge.active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.inactive {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.app-description {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: 16px;\n}\n\n.scope-count {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scope-count i {\n color: var(--mj-color-violet-500);\n}\n\n.expand-icon {\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n/* Expanded Details */\n.app-details {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: 0;\n}\n\n.details-section {\n margin-top: 16px;\n}\n\n.details-section h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 12px 0;\n}\n\n.scope-rules {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-rule {\n display: flex;\n align-items: flex-start;\n padding: 10px 12px;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.rule-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.rule-icon.pattern-include {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.rule-icon.pattern-exclude {\n background: var(--mj-color-brand-100);\n color: var(--mj-brand-primary-hover);\n}\n\n.rule-icon.pattern-deny {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.rule-info {\n flex: 1;\n min-width: 0;\n}\n\n.rule-scope {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.rule-pattern {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n.rule-pattern code {\n font-family: monospace;\n font-size: 12px;\n background: var(--mj-bg-surface-active);\n padding: 2px 6px;\n border-radius: 4px;\n color: var(--mj-text-primary);\n}\n\n.pattern-type {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.priority {\n font-size: 11px;\n color: var(--mj-color-violet-500);\n}\n\n.empty-scopes {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px;\n color: var(--mj-text-secondary);\n text-align: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.empty-scopes i {\n font-size: 24px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n\n/* Legacy .details-actions removed - buttons now in header */\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state span {\n font-size: 16px;\n font-weight: 500;\n}\n\n.empty-state p {\n font-size: 14px;\n margin-top: 8px;\n}\n\n/* ========================================\n Slide-out Panel Styles\n ======================================== */\n\n/* Backdrop */\n.slideout-backdrop {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 100;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Slide-out Panel */\n.slideout-panel {\n position: absolute;\n top: 0;\n right: 0;\n width: 570px;\n height: 100%;\n max-height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n transform: translateX(100%);\n}\n\n.slideout-panel.open {\n transform: translateX(0);\n}\n\n/* Resize handle */\n.slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 6px;\n height: 100%;\n cursor: ew-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s ease;\n}\n\n.slideout-resize-handle:hover,\n.slideout-resize-handle.resizing {\n background: color-mix(in srgb, var(--mj-color-violet-500) 30%, transparent);\n}\n\n.slideout-resize-handle::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 40px;\n background: var(--mj-color-neutral-300);\n border-radius: 2px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.slideout-resize-handle:hover::after {\n opacity: 1;\n}\n\n/* Panel Header */\n.slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title i {\n color: var(--mj-color-violet-500);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-title span:first-of-type {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.status-pill {\n font-size: 11px;\n font-weight: 500;\n padding: 3px 10px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.status-pill.active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-color-neutral-700);\n}\n\n/* Panel Tabs */\n.slideout-tabs {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\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.2s ease;\n}\n\n.slideout-tab:hover {\n background: var(--mj-border-default);\n color: var(--mj-color-neutral-700);\n}\n\n.slideout-tab.active {\n background: var(--mj-color-violet-500);\n color: var(--mj-text-inverse);\n}\n\n.slideout-tab i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.slideout-tab:not(.active) .tab-badge {\n background: var(--mj-border-default); /* tab badge neutral bg */\n color: var(--mj-color-neutral-700);\n}\n\n/* Panel Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.tab-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.scopes-panel {\n height: 100%;\n}\n\n/* Form Section */\n.form-section {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n/* Form Fields */\n.form-field {\n margin-bottom: 20px;\n}\n\n.form-field:last-of-type {\n margin-bottom: 0;\n}\n\n.form-field label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-color-neutral-700);\n margin-bottom: 8px;\n letter-spacing: 0.01em;\n}\n\n.form-input {\n width: 100%;\n}\n\n.form-textarea {\n width: 100%;\n resize: vertical;\n min-height: 80px;\n}\n\n:host ::ng-deep .form-input .k-input,\n:host ::ng-deep .form-textarea .k-input-inner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .form-input:focus-within,\n:host ::ng-deep .form-textarea:focus-within {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-color-violet-500) 10%, transparent); /* violet focus ring */\n}\n\n/* Slideout Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default); /* category/slideout separator */\n flex-shrink: 0;\n}\n\n:host ::ng-deep .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary {\n background: linear-gradient(135deg, var(--mj-color-violet-500) 0%, var(--mj-color-violet-600) 100%);\n border: none;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-color-violet-500) 30%, transparent);\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-color-violet-500) 40%, transparent);\n}\n\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.checkbox-label:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-300);\n}\n\n.checkbox-label input {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.checkbox-label span:first-of-type {\n font-weight: 600;\n color: var(--mj-color-neutral-700);\n font-size: 14px;\n}\n\n.checkbox-hint {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n line-height: 1.4;\n}\n\n/* Legacy dialog-actions removed - now using slideout-footer */\n\n/* ========================================\n Scopes Panel - Slide-out Layout\n ======================================== */\n\n.scopes-intro {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border: 1px solid var(--mj-status-info-border);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n margin-bottom: 16px;\n line-height: 1.4;\n}\n\n.scopes-intro i {\n color: var(--mj-status-info);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.scope-categories-list {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.scope-category-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.scope-category-card .category-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.scope-category-card .category-header:hover {\n background: var(--mj-bg-page);\n}\n\n.scope-category-card .category-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.scope-category-card .category-left i {\n font-size: 14px;\n}\n\n.scope-category-card .category-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.category-count-badge {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.scope-category-card .category-right {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.category-all-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-chevron {\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.category-scopes-list {\n border-top: 1px solid var(--mj-border-default); /* category/slideout separator */\n padding: 8px;\n max-height: 280px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.scope-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-page);\n transition: all 0.2s ease;\n}\n\n.scope-row:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.scope-row.selected {\n background: var(--mj-color-violet-100);\n border: 1px solid var(--mj-color-violet-300);\n}\n\n.scope-select {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n flex: 1;\n min-width: 0;\n cursor: pointer;\n}\n\n.scope-select input {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.scope-label {\n flex: 1;\n min-width: 0;\n}\n\n.scope-path {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-primary);\n font-family: 'SF Mono', 'Consolas', monospace;\n word-break: break-word;\n}\n\n.scope-description {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Pattern config for selected scopes - read-only display */\n.scope-pattern-display {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: 'SF Mono', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-color-neutral-700);\n}\n\n.pattern-tag.include {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.pattern-tag.exclude {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-700);\n}\n\n.pattern-tag i {\n font-size: 10px;\n}\n\n/* Editable pattern config - shown on hover/edit */\n.scope-pattern-config {\n display: none;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.scope-row:hover .scope-pattern-config,\n.scope-row.editing .scope-pattern-config {\n display: flex;\n}\n\n.scope-row:hover .scope-pattern-display,\n.scope-row.editing .scope-pattern-display {\n display: none;\n}\n\n.pattern-field {\n width: 60px;\n}\n\n:host ::ng-deep .pattern-field .k-input {\n padding: 3px 6px;\n font-size: 11px;\n border-radius: 4px;\n height: 26px;\n}\n\n.type-field {\n width: 75px;\n}\n\n:host ::ng-deep .type-field .k-dropdownlist {\n font-size: 11px;\n height: 26px;\n}\n\n:host ::ng-deep .type-field .k-input-inner {\n padding: 2px 6px;\n font-size: 11px;\n}\n\n.empty-scopes-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.empty-scopes-message i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Legacy dialog styles removed - now using slide-out panels */\n"] }]
1052
+ args: [{ standalone: false, selector: 'mj-api-applications-panel', template: "<div class=\"applications-panel\" [class.panel-open]=\"ShowEditPanel || ShowCreatePanel\">\n @if (IsLoading) {\n <mj-loading text=\"Loading applications...\"></mj-loading>\n }\n\n @if (!IsLoading) {\n <!-- Header -->\n <div class=\"panel-header\">\n <div class=\"header-left\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-cube\"></i>\n API Applications\n </h3>\n <p class=\"panel-subtitle\">Manage applications and their default scope permissions</p>\n </div>\n <button class=\"btn-create\" (click)=\"openCreatePanel()\">\n <i class=\"fa-solid fa-plus\"></i>\n New Application\n </button>\n </div>\n <!-- Messages -->\n @if (SuccessMessage) {\n <div class=\"message success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n {{SuccessMessage}}\n </div>\n }\n @if (ErrorMessage) {\n <div class=\"message error\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n {{ErrorMessage}}\n </div>\n }\n <!-- Applications Grid -->\n <div class=\"applications-grid\">\n @for (appItem of Applications; track appItem) {\n <div class=\"app-card\"\n [class.inactive]=\"!appItem.application.IsActive\"\n [class.expanded]=\"appItem.expanded\">\n <div class=\"app-header\">\n <div class=\"app-header-main\" (click)=\"toggleExpanded(appItem)\">\n <div class=\"app-icon\">\n <i class=\"fa-solid fa-cube\"></i>\n </div>\n <div class=\"app-info\">\n <div class=\"app-name\">\n {{appItem.application.Name}}\n <span class=\"status-badge\" [class.active]=\"appItem.application.IsActive\"\n [class.inactive]=\"!appItem.application.IsActive\">\n {{appItem.application.IsActive ? 'Active' : 'Inactive'}}\n </span>\n </div>\n @if (appItem.application.Description) {\n <div class=\"app-description\">\n {{appItem.application.Description}}\n </div>\n }\n </div>\n <div class=\"app-stats\">\n <div class=\"scope-count\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n {{appItem.scopeCount}} scopes\n </div>\n <i class=\"fa-solid expand-icon\"\n [class.fa-chevron-down]=\"!appItem.expanded\"\n [class.fa-chevron-up]=\"appItem.expanded\"></i>\n </div>\n </div>\n <button class=\"app-edit-btn\" (click)=\"openEditPanel(appItem); $event.stopPropagation()\" title=\"Edit Application\">\n <i class=\"fa-solid fa-pencil\"></i>\n </button>\n </div>\n <!-- Expanded Content -->\n @if (appItem.expanded) {\n <div class=\"app-details\">\n <div class=\"details-section\">\n <h4>Scope Ceiling Rules</h4>\n @if (appItem.scopes.length > 0) {\n <div class=\"scope-rules\">\n @for (scope of appItem.scopes; track scope) {\n <div class=\"scope-rule\">\n <div class=\"rule-icon\" [ngClass]=\"getPatternClass(scope.PatternType, scope.IsDeny)\">\n <i [class]=\"getPatternIcon(scope.PatternType, scope.IsDeny)\"></i>\n </div>\n <div class=\"rule-info\">\n <div class=\"rule-scope\">{{getScopeName(scope.ScopeID)}}</div>\n <div class=\"rule-pattern\">\n <code>{{scope.ResourcePattern}}</code>\n <span class=\"pattern-type\">{{scope.PatternType}}</span>\n @if (scope.Priority > 0) {\n <span class=\"priority\">\n Priority: {{scope.Priority}}\n </span>\n }\n </div>\n </div>\n </div>\n }\n </div>\n }\n @if (appItem.scopes.length === 0) {\n <div class=\"empty-scopes\">\n <i class=\"fa-solid fa-shield-xmark\"></i>\n <span>No scope rules defined - all access denied by default</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n }\n <!-- Empty State -->\n @if (Applications.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-cube\"></i>\n <span>No applications configured</span>\n <p>Create an application to define scope ceilings for API key access</p>\n </div>\n }\n </div>\n }\n\n <!-- Slide-out Backdrop -->\n @if (ShowEditPanel || ShowCreatePanel) {\n <div class=\"slideout-backdrop\" (click)=\"closePanel()\"></div>\n }\n\n <!-- Create Panel (Slide-out) -->\n <div class=\"slideout-panel\" [class.open]=\"ShowCreatePanel\">\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-plus-circle\"></i>\n <span>New Application</span>\n </div>\n <button class=\"slideout-close\" (click)=\"closePanel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <div class=\"form-section\">\n <div class=\"form-field\">\n <label>Application Name *</label>\n <input kendoTextBox [(ngModel)]=\"EditName\"\n placeholder=\"e.g., MJAPI, MCP Server, Portal\"\n class=\"form-input\" />\n </div>\n\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n placeholder=\"Describe the application's purpose...\"\n [rows]=\"3\"\n class=\"form-textarea\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox [(ngModel)]=\"EditIsActive\" />\n <div>\n <span>Active</span>\n <span class=\"checkbox-hint\">Inactive applications cannot be used with API keys</span>\n </div>\n </label>\n </div>\n </div>\n </div>\n\n <div class=\"slideout-footer\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"!EditName.trim() || IsSaving\"\n (click)=\"saveApplication()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Create Application\n </span>\n }\n </button>\n <button kendoButton (click)=\"closePanel()\">Cancel</button>\n </div>\n </div>\n\n <!-- Edit Panel (Slide-out) -->\n <div class=\"slideout-panel\" [class.open]=\"ShowEditPanel\" [style.width.px]=\"PanelWidth\">\n <!-- Resize Handle -->\n <div class=\"slideout-resize-handle\"\n [class.resizing]=\"IsResizing\"\n (mousedown)=\"startResize($event)\"></div>\n <div class=\"slideout-header\">\n <div class=\"slideout-title\">\n <i class=\"fa-solid fa-cube\"></i>\n <span>{{EditingApplication?.Name}}</span>\n <span class=\"status-pill\" [class.active]=\"EditIsActive\">\n {{EditIsActive ? 'Active' : 'Inactive'}}\n </span>\n </div>\n <button class=\"slideout-close\" (click)=\"closePanel()\" title=\"Close\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n <!-- Tab Bar -->\n <div class=\"slideout-tabs\">\n <button class=\"slideout-tab\" [class.active]=\"EditTab === 'details'\"\n (click)=\"EditTab = 'details'\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Details\n </button>\n <button class=\"slideout-tab\" [class.active]=\"EditTab === 'scopes'\"\n (click)=\"EditTab = 'scopes'\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n Scopes\n <span class=\"tab-badge\">{{getSelectedScopeCount()}}</span>\n </button>\n </div>\n\n <div class=\"slideout-content\">\n <!-- Details Tab -->\n @if (EditTab === 'details') {\n <div class=\"tab-panel\">\n <div class=\"form-section\">\n <div class=\"form-field\">\n <label>Application Name *</label>\n <input kendoTextBox [(ngModel)]=\"EditName\"\n placeholder=\"e.g., MJAPI, MCP Server, Portal\"\n class=\"form-input\" />\n </div>\n <div class=\"form-field\">\n <label>Description</label>\n <textarea kendoTextArea [(ngModel)]=\"EditDescription\"\n placeholder=\"Describe the application's purpose...\"\n [rows]=\"4\"\n class=\"form-textarea\"></textarea>\n </div>\n <div class=\"form-field\">\n <label class=\"checkbox-label\">\n <input type=\"checkbox\" kendoCheckBox [(ngModel)]=\"EditIsActive\" />\n <div>\n <span>Active</span>\n <span class=\"checkbox-hint\">Inactive applications cannot be used with API keys</span>\n </div>\n </label>\n </div>\n </div>\n </div>\n }\n\n <!-- Scopes Tab -->\n @if (EditTab === 'scopes') {\n <div class=\"tab-panel scopes-panel\">\n <div class=\"scopes-intro\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <span>Define the maximum permissions this application can grant to API keys.</span>\n </div>\n <div class=\"scope-categories-list\">\n @for (category of ScopeCategories; track category) {\n <div class=\"scope-category-card\">\n <div class=\"category-header\" (click)=\"toggleScopeCategory(category)\">\n <div class=\"category-left\">\n <i [class]=\"category.icon\" [style.color]=\"category.color\"></i>\n <span class=\"category-name\">{{category.name}}</span>\n <span class=\"category-count-badge\">\n {{getCategorySelectedCount(category)}}/{{category.scopes.length}}\n </span>\n </div>\n <div class=\"category-right\">\n <label class=\"category-all-toggle\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" kendoCheckBox\n [checked]=\"category.allSelected\"\n (change)=\"toggleCategoryAll(category)\" />\n <span>All</span>\n </label>\n <i class=\"fa-solid category-chevron\"\n [class.fa-chevron-down]=\"!category.expanded\"\n [class.fa-chevron-up]=\"category.expanded\"></i>\n </div>\n </div>\n @if (category.expanded) {\n <div class=\"category-scopes-list\">\n @for (selection of category.scopes; track selection) {\n <div class=\"scope-row\"\n [class.selected]=\"selection.selected\">\n <label class=\"scope-select\">\n <input type=\"checkbox\" kendoCheckBox\n [(ngModel)]=\"selection.selected\"\n (change)=\"updateCategoryState(category)\" />\n <div class=\"scope-label\">\n <span class=\"scope-path\">{{selection.displayName || '(unnamed scope)'}}</span>\n @if (selection.scope.Description) {\n <span class=\"scope-description\">\n {{selection.scope.Description}}\n </span>\n }\n </div>\n </label>\n <!-- Read-only pattern display -->\n @if (selection.selected) {\n <div class=\"scope-pattern-display\">\n <span class=\"pattern-tag\" [class.include]=\"selection.patternType === 'Include'\"\n [class.exclude]=\"selection.patternType === 'Exclude'\">\n <i class=\"fa-solid\" [class.fa-check]=\"selection.patternType === 'Include'\"\n [class.fa-minus]=\"selection.patternType === 'Exclude'\"></i>\n {{selection.pattern || '*'}}\n </span>\n </div>\n }\n <!-- Editable pattern config - shown on hover -->\n @if (selection.selected) {\n <div class=\"scope-pattern-config\">\n <input kendoTextBox [(ngModel)]=\"selection.pattern\"\n placeholder=\"*\"\n class=\"pattern-field\"\n title=\"Resource Pattern\" />\n <kendo-dropdownlist [(ngModel)]=\"selection.patternType\"\n [data]=\"['Include', 'Exclude']\"\n [valuePrimitive]=\"true\"\n class=\"type-field\"\n title=\"Pattern Type\">\n </kendo-dropdownlist>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n }\n @if (ScopeCategories.length === 0) {\n <div class=\"empty-scopes-message\">\n <i class=\"fa-solid fa-shield-xmark\"></i>\n <span>No scopes available</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <div class=\"slideout-footer\">\n <button kendoButton [themeColor]=\"'primary'\"\n [disabled]=\"!EditName.trim() || IsSaving\"\n (click)=\"saveAll()\">\n @if (IsSaving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n }\n @if (!IsSaving) {\n <span>\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n </span>\n }\n </button>\n <button kendoButton (click)=\"closePanel()\">Cancel</button>\n </div>\n </div>\n</div>\n", styles: [".applications-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.applications-panel.panel-open {\n overflow: hidden;\n}\n\n/* Panel Header */\n.panel-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 24px;\n}\n\n.header-left {\n flex: 1;\n}\n\n.panel-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 18px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 4px 0;\n}\n\n.panel-title i {\n color: var(--mj-brand-primary);\n}\n\n.panel-subtitle {\n font-size: 14px;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n.btn-create {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 20px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 8px;\n font-weight: 600;\n font-size: 14px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.btn-create:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n/* Messages */\n.message {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 12px 16px;\n border-radius: 8px;\n margin-bottom: 16px;\n font-size: 14px;\n}\n\n.message.success {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.message.error {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error-border);\n}\n\n/* Applications Grid */\n.applications-grid {\n display: flex;\n flex-direction: column;\n gap: 16px;\n flex: 1;\n overflow-y: auto;\n}\n\n.app-card {\n background: var(--mj-bg-surface);\n border-radius: 12px;\n box-shadow: var(--mj-shadow-md);\n overflow: hidden;\n transition: box-shadow 0.2s ease;\n}\n\n.app-card:hover {\n box-shadow: var(--mj-shadow-lg);\n}\n\n.app-card.inactive {\n opacity: 0.7;\n}\n\n.app-header {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.app-header-main {\n display: flex;\n align-items: center;\n flex: 1;\n cursor: pointer;\n transition: background 0.2s ease;\n border-radius: 8px;\n padding: 4px;\n margin: -4px;\n}\n\n.app-header-main:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.app-edit-btn {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.app-edit-btn:hover {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.app-icon {\n width: 48px;\n height: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--mj-brand-primary);\n border-radius: 10px;\n margin-right: 16px;\n flex-shrink: 0;\n}\n\n.app-icon i {\n font-size: 20px;\n color: var(--mj-text-inverse);\n}\n\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.status-badge {\n font-size: 11px;\n font-weight: 500;\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.status-badge.active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.status-badge.inactive {\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n}\n\n.app-description {\n font-size: 13px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.app-stats {\n display: flex;\n align-items: center;\n gap: 16px;\n margin-left: 16px;\n}\n\n.scope-count {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--mj-text-secondary);\n}\n\n.scope-count i {\n color: var(--mj-brand-primary);\n}\n\n.expand-icon {\n color: var(--mj-text-muted);\n transition: transform 0.2s ease;\n}\n\n/* Expanded Details */\n.app-details {\n padding: 0 20px 20px 20px;\n border-top: 1px solid var(--mj-border-default);\n margin-top: 0;\n}\n\n.details-section {\n margin-top: 16px;\n}\n\n.details-section h4 {\n font-size: 14px;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 12px 0;\n}\n\n.scope-rules {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.scope-rule {\n display: flex;\n align-items: flex-start;\n padding: 10px 12px;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.rule-icon {\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n margin-right: 12px;\n flex-shrink: 0;\n}\n\n.rule-icon.pattern-include {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-600);\n}\n\n.rule-icon.pattern-exclude {\n background: var(--mj-color-brand-100);\n color: var(--mj-brand-primary-hover);\n}\n\n.rule-icon.pattern-deny {\n background: var(--mj-color-error-100);\n color: var(--mj-color-error-600);\n}\n\n.rule-info {\n flex: 1;\n min-width: 0;\n}\n\n.rule-scope {\n font-size: 13px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.rule-pattern {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 4px;\n flex-wrap: wrap;\n}\n\n.rule-pattern code {\n font-family: monospace;\n font-size: 12px;\n background: var(--mj-bg-surface-active);\n padding: 2px 6px;\n border-radius: 4px;\n color: var(--mj-text-primary);\n}\n\n.pattern-type {\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.priority {\n font-size: 11px;\n color: var(--mj-brand-primary);\n}\n\n.empty-scopes {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 24px;\n color: var(--mj-text-secondary);\n text-align: center;\n background: var(--mj-bg-page);\n border-radius: 8px;\n}\n\n.empty-scopes i {\n font-size: 24px;\n margin-bottom: 8px;\n opacity: 0.5;\n}\n\n/* Legacy .details-actions removed - buttons now in header */\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 48px;\n color: var(--mj-text-secondary);\n text-align: center;\n}\n\n.empty-state i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.5;\n}\n\n.empty-state span {\n font-size: 16px;\n font-weight: 500;\n}\n\n.empty-state p {\n font-size: 14px;\n margin-top: 8px;\n}\n\n/* ========================================\n Slide-out Panel Styles\n ======================================== */\n\n/* Backdrop */\n.slideout-backdrop {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 100;\n animation: fadeIn 0.2s ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Slide-out Panel */\n.slideout-panel {\n position: absolute;\n top: 0;\n right: 0;\n width: 570px;\n height: 100%;\n max-height: 100%;\n background: var(--mj-bg-surface);\n box-shadow: -8px 0 32px var(--mj-bg-overlay);\n z-index: 101;\n display: flex;\n flex-direction: column;\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: hidden;\n transform: translateX(100%);\n}\n\n.slideout-panel.open {\n transform: translateX(0);\n}\n\n/* Resize handle */\n.slideout-resize-handle {\n position: absolute;\n top: 0;\n left: 0;\n width: 6px;\n height: 100%;\n cursor: ew-resize;\n background: transparent;\n z-index: 10;\n transition: background 0.2s ease;\n}\n\n.slideout-resize-handle:hover,\n.slideout-resize-handle.resizing {\n background: color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n.slideout-resize-handle::after {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2px;\n height: 40px;\n background: var(--mj-color-neutral-300);\n border-radius: 2px;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.slideout-resize-handle:hover::after {\n opacity: 1;\n}\n\n/* Panel Header */\n.slideout-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-title {\n display: flex;\n align-items: center;\n gap: 12px;\n font-weight: 600;\n font-size: 17px;\n color: var(--mj-text-primary);\n flex: 1;\n min-width: 0;\n}\n\n.slideout-title i {\n color: var(--mj-brand-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.slideout-title span:first-of-type {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.status-pill {\n font-size: 11px;\n font-weight: 500;\n padding: 3px 10px;\n border-radius: 12px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n flex-shrink: 0;\n}\n\n.status-pill.active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.slideout-close {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: transparent;\n border: none;\n border-radius: 8px;\n color: var(--mj-text-muted);\n cursor: pointer;\n transition: all 0.2s ease;\n flex-shrink: 0;\n}\n\n.slideout-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n\n/* Panel Tabs */\n.slideout-tabs {\n display: flex;\n gap: 4px;\n padding: 12px 24px;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.slideout-tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 18px;\n background: transparent;\n border: none;\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.2s ease;\n}\n\n.slideout-tab:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.slideout-tab.active {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n}\n\n.slideout-tab i {\n font-size: 14px;\n}\n\n.tab-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.slideout-tab:not(.active) .tab-badge {\n background: var(--mj-border-default); /* tab badge neutral bg */\n color: var(--mj-text-secondary);\n}\n\n/* Panel Content */\n.slideout-content {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.tab-panel {\n height: 100%;\n display: flex;\n flex-direction: column;\n}\n\n.scopes-panel {\n height: 100%;\n}\n\n/* Form Section */\n.form-section {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n/* Form Fields */\n.form-field {\n margin-bottom: 20px;\n}\n\n.form-field:last-of-type {\n margin-bottom: 0;\n}\n\n.form-field label {\n display: block;\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-secondary);\n margin-bottom: 8px;\n letter-spacing: 0.01em;\n}\n\n.form-input {\n width: 100%;\n}\n\n.form-textarea {\n width: 100%;\n resize: vertical;\n min-height: 80px;\n}\n\n:host ::ng-deep .form-input .k-input,\n:host ::ng-deep .form-textarea .k-input-inner {\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 14px;\n border-color: var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .form-input:focus-within,\n:host ::ng-deep .form-textarea:focus-within {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n/* Slideout Footer */\n.slideout-footer {\n display: flex;\n gap: 12px;\n padding: 16px 24px;\n background: var(--mj-bg-page);\n border-top: 1px solid var(--mj-border-default); /* category/slideout separator */\n flex-shrink: 0;\n}\n\n:host ::ng-deep .slideout-footer .k-button {\n min-width: 100px;\n padding: 10px 20px;\n font-weight: 600;\n border-radius: 8px;\n transition: all 0.2s ease;\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary {\n background: var(--mj-brand-primary);\n border: none;\n box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 30%, transparent);\n}\n\n:host ::ng-deep .slideout-footer .k-button-solid-primary:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 12px color-mix(in srgb, var(--mj-brand-primary) 40%, transparent);\n}\n\n.checkbox-label {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n cursor: pointer;\n padding: 12px 16px;\n background: var(--mj-bg-page);\n border-radius: 10px;\n border: 1px solid var(--mj-border-default);\n transition: all 0.2s ease;\n}\n\n.checkbox-label:hover {\n background: var(--mj-bg-surface-sunken);\n border-color: var(--mj-color-neutral-300);\n}\n\n.checkbox-label input {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.checkbox-label span:first-of-type {\n font-weight: 600;\n color: var(--mj-text-secondary);\n font-size: 14px;\n}\n\n.checkbox-hint {\n display: block;\n font-size: 12px;\n color: var(--mj-text-secondary);\n margin-top: 4px;\n line-height: 1.4;\n}\n\n/* Legacy dialog-actions removed - now using slideout-footer */\n\n/* ========================================\n Scopes Panel - Slide-out Layout\n ======================================== */\n\n.scopes-intro {\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 12px 16px;\n background: var(--mj-status-info-bg);\n border: 1px solid var(--mj-status-info-border);\n border-radius: 10px;\n font-size: 13px;\n color: var(--mj-status-info-text);\n margin-bottom: 16px;\n line-height: 1.4;\n}\n\n.scopes-intro i {\n color: var(--mj-status-info);\n font-size: 14px;\n flex-shrink: 0;\n margin-top: 1px;\n}\n\n.scope-categories-list {\n flex: 1;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.scope-category-card {\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: 10px;\n overflow: hidden;\n}\n\n.scope-category-card .category-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n cursor: pointer;\n transition: background 0.2s ease;\n}\n\n.scope-category-card .category-header:hover {\n background: var(--mj-bg-page);\n}\n\n.scope-category-card .category-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.scope-category-card .category-left i {\n font-size: 14px;\n}\n\n.scope-category-card .category-name {\n font-size: 13px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.category-count-badge {\n font-size: 11px;\n color: var(--mj-text-secondary);\n background: var(--mj-bg-surface-sunken);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.scope-category-card .category-right {\n display: flex;\n align-items: center;\n gap: 14px;\n}\n\n.category-all-toggle {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 12px;\n color: var(--mj-text-secondary);\n cursor: pointer;\n}\n\n.category-chevron {\n color: var(--mj-text-muted);\n font-size: 11px;\n}\n\n.category-scopes-list {\n border-top: 1px solid var(--mj-border-default); /* category/slideout separator */\n padding: 8px;\n max-height: 280px;\n overflow-y: auto;\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.scope-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 10px 12px;\n border-radius: 8px;\n background: var(--mj-bg-page);\n transition: all 0.2s ease;\n}\n\n.scope-row:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n.scope-row.selected {\n background: var(--mj-color-violet-100);\n border: 1px solid var(--mj-color-violet-300);\n}\n\n.scope-select {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n flex: 1;\n min-width: 0;\n cursor: pointer;\n}\n\n.scope-select input {\n margin-top: 2px;\n flex-shrink: 0;\n}\n\n.scope-label {\n flex: 1;\n min-width: 0;\n}\n\n.scope-path {\n font-size: 12px;\n font-weight: 500;\n color: var(--mj-text-primary);\n font-family: 'SF Mono', 'Consolas', monospace;\n word-break: break-word;\n}\n\n.scope-description {\n display: block;\n font-size: 11px;\n color: var(--mj-text-secondary);\n margin-top: 2px;\n line-height: 1.3;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* Pattern config for selected scopes - read-only display */\n.scope-pattern-display {\n display: flex;\n align-items: center;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 4px;\n font-family: 'SF Mono', 'Consolas', monospace;\n font-size: 11px;\n color: var(--mj-text-secondary);\n}\n\n.pattern-tag.include {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n}\n\n.pattern-tag.exclude {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.pattern-tag i {\n font-size: 10px;\n}\n\n/* Editable pattern config - shown on hover/edit */\n.scope-pattern-config {\n display: none;\n gap: 6px;\n margin-left: auto;\n flex-shrink: 0;\n}\n\n.scope-row:hover .scope-pattern-config,\n.scope-row.editing .scope-pattern-config {\n display: flex;\n}\n\n.scope-row:hover .scope-pattern-display,\n.scope-row.editing .scope-pattern-display {\n display: none;\n}\n\n.pattern-field {\n width: 60px;\n}\n\n:host ::ng-deep .pattern-field .k-input {\n padding: 3px 6px;\n font-size: 11px;\n border-radius: 4px;\n height: 26px;\n}\n\n.type-field {\n width: 75px;\n}\n\n:host ::ng-deep .type-field .k-dropdownlist {\n font-size: 11px;\n height: 26px;\n}\n\n:host ::ng-deep .type-field .k-input-inner {\n padding: 2px 6px;\n font-size: 11px;\n}\n\n.empty-scopes-message {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 32px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.empty-scopes-message i {\n font-size: 32px;\n margin-bottom: 12px;\n opacity: 0.5;\n}\n\n/* Legacy dialog styles removed - now using slide-out panels */\n"] }]
1053
1053
  }], () => [{ type: i0.ChangeDetectorRef }], { ApplicationUpdated: [{
1054
1054
  type: Output
1055
1055
  }], onMouseMove: [{