@memberjunction/ng-dashboards 5.26.0 → 5.27.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 (98) hide show
  1. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts +96 -0
  2. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.d.ts.map +1 -0
  3. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js +710 -0
  4. package/dist/AI/components/analytics/agent-runs/agent-run-analysis.component.js.map +1 -0
  5. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts +52 -0
  6. package/dist/AI/components/analytics/ai-analytics-resource.component.d.ts.map +1 -0
  7. package/dist/AI/components/analytics/ai-analytics-resource.component.js +356 -0
  8. package/dist/AI/components/analytics/ai-analytics-resource.component.js.map +1 -0
  9. package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts +52 -0
  10. package/dist/AI/components/analytics/analytics-filter-bar.component.d.ts.map +1 -0
  11. package/dist/AI/components/analytics/analytics-filter-bar.component.js +306 -0
  12. package/dist/AI/components/analytics/analytics-filter-bar.component.js.map +1 -0
  13. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts +81 -0
  14. package/dist/AI/components/analytics/cost-budget/cost-budget.component.d.ts.map +1 -0
  15. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js +744 -0
  16. package/dist/AI/components/analytics/cost-budget/cost-budget.component.js.map +1 -0
  17. package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts +61 -0
  18. package/dist/AI/components/analytics/error-analysis/error-analysis.component.d.ts.map +1 -0
  19. package/dist/AI/components/analytics/error-analysis/error-analysis.component.js +490 -0
  20. package/dist/AI/components/analytics/error-analysis/error-analysis.component.js.map +1 -0
  21. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts +77 -0
  22. package/dist/AI/components/analytics/executive-summary/executive-summary.component.d.ts.map +1 -0
  23. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js +673 -0
  24. package/dist/AI/components/analytics/executive-summary/executive-summary.component.js.map +1 -0
  25. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts +65 -0
  26. package/dist/AI/components/analytics/model-performance/model-performance.component.d.ts.map +1 -0
  27. package/dist/AI/components/analytics/model-performance/model-performance.component.js +537 -0
  28. package/dist/AI/components/analytics/model-performance/model-performance.component.js.map +1 -0
  29. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts +131 -0
  30. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.d.ts.map +1 -0
  31. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js +1030 -0
  32. package/dist/AI/components/analytics/prompt-runs/prompt-run-analysis.component.js.map +1 -0
  33. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts +78 -0
  34. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.d.ts.map +1 -0
  35. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js +569 -0
  36. package/dist/AI/components/analytics/usage-patterns/usage-patterns.component.js.map +1 -0
  37. package/dist/AI/components/execution-monitoring.component.d.ts.map +1 -1
  38. package/dist/AI/components/execution-monitoring.component.js +4 -14
  39. package/dist/AI/components/execution-monitoring.component.js.map +1 -1
  40. package/dist/AI/components/overview/ai-overview-hub.component.d.ts +58 -0
  41. package/dist/AI/components/overview/ai-overview-hub.component.d.ts.map +1 -0
  42. package/dist/AI/components/overview/ai-overview-hub.component.js +315 -0
  43. package/dist/AI/components/overview/ai-overview-hub.component.js.map +1 -0
  44. package/dist/AI/components/prompts/prompt-management.component.js +1 -1
  45. package/dist/AI/components/prompts/prompt-management.component.js.map +1 -1
  46. package/dist/AI/index.d.ts +11 -0
  47. package/dist/AI/index.d.ts.map +1 -1
  48. package/dist/AI/index.js +13 -0
  49. package/dist/AI/index.js.map +1 -1
  50. package/dist/AI/interfaces/analytics-preferences.interface.d.ts +50 -0
  51. package/dist/AI/interfaces/analytics-preferences.interface.d.ts.map +1 -0
  52. package/dist/AI/interfaces/analytics-preferences.interface.js +9 -0
  53. package/dist/AI/interfaces/analytics-preferences.interface.js.map +1 -0
  54. package/dist/ComponentStudio/components/artifact-load-dialog.component.d.ts.map +1 -1
  55. package/dist/ComponentStudio/components/artifact-load-dialog.component.js +1 -1
  56. package/dist/ComponentStudio/components/artifact-load-dialog.component.js.map +1 -1
  57. package/dist/Home/home-dashboard.component.js +2 -2
  58. package/dist/MCP/index.d.ts +1 -0
  59. package/dist/MCP/index.d.ts.map +1 -1
  60. package/dist/MCP/index.js +2 -0
  61. package/dist/MCP/index.js.map +1 -1
  62. package/dist/MCP/mcp-dashboard.component.d.ts +1 -0
  63. package/dist/MCP/mcp-dashboard.component.d.ts.map +1 -1
  64. package/dist/MCP/mcp-dashboard.component.js +5 -4
  65. package/dist/MCP/mcp-dashboard.component.js.map +1 -1
  66. package/dist/MCP/mcp-resource.component.d.ts +6 -5
  67. package/dist/MCP/mcp-resource.component.d.ts.map +1 -1
  68. package/dist/MCP/mcp-resource.component.js +7 -8
  69. package/dist/MCP/mcp-resource.component.js.map +1 -1
  70. package/dist/ai-dashboards.module.d.ts +27 -17
  71. package/dist/ai-dashboards.module.d.ts.map +1 -1
  72. package/dist/ai-dashboards.module.js +66 -3
  73. package/dist/ai-dashboards.module.js.map +1 -1
  74. package/dist/public-api.d.ts +1 -1
  75. package/dist/public-api.d.ts.map +1 -1
  76. package/dist/public-api.js +1 -1
  77. package/dist/public-api.js.map +1 -1
  78. package/package.json +48 -48
  79. package/dist/__tests__/analytics-resource.test.d.ts +0 -2
  80. package/dist/__tests__/analytics-resource.test.d.ts.map +0 -1
  81. package/dist/__tests__/analytics-resource.test.js +0 -181
  82. package/dist/__tests__/analytics-resource.test.js.map +0 -1
  83. package/dist/__tests__/dashboards.test.d.ts +0 -2
  84. package/dist/__tests__/dashboards.test.d.ts.map +0 -1
  85. package/dist/__tests__/dashboards.test.js +0 -40
  86. package/dist/__tests__/dashboards.test.js.map +0 -1
  87. package/dist/__tests__/integration-data-service.test.d.ts +0 -2
  88. package/dist/__tests__/integration-data-service.test.d.ts.map +0 -1
  89. package/dist/__tests__/integration-data-service.test.js +0 -132
  90. package/dist/__tests__/integration-data-service.test.js.map +0 -1
  91. package/dist/__tests__/mapping-validation.test.d.ts +0 -2
  92. package/dist/__tests__/mapping-validation.test.d.ts.map +0 -1
  93. package/dist/__tests__/mapping-validation.test.js +0 -170
  94. package/dist/__tests__/mapping-validation.test.js.map +0 -1
  95. package/dist/__tests__/scheduling.test.d.ts +0 -2
  96. package/dist/__tests__/scheduling.test.d.ts.map +0 -1
  97. package/dist/__tests__/scheduling.test.js +0 -205
  98. package/dist/__tests__/scheduling.test.js.map +0 -1
@@ -2345,7 +2345,7 @@ let HomeDashboardComponent = class HomeDashboardComponent extends BaseResourceCo
2345
2345
  i0.ɵɵconditional(ctx.hasSidebarContent && !ctx.sidebarOpen ? 14 : -1);
2346
2346
  i0.ɵɵadvance();
2347
2347
  i0.ɵɵtwoWayProperty("ShowDialog", ctx.showConfigDialog);
2348
- } }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective, i5.LoadingComponent, i6.UserAppConfigComponent, i7.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: 80px; \n\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n\n\n.apps-section[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n\n\n.app-icon-wrapper[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] {\n background: var(--app-color);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.nav-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.app-arrow[_ngcontent-%COMP%] {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-arrow[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\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: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .quick-access-sidebar[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n\n\n.sidebar-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-info-50);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n.pinned-section[_ngcontent-%COMP%] {\n margin-bottom: 32px;\n}\n\n.pinned-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.pinned-actions[_ngcontent-%COMP%] {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n\n\n.edit-mode-banner[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.pin-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 40px;\n color: var(--mj-text-disabled);\n margin-bottom: 16px;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n margin: 0 0 6px 0;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 360px;\n margin: 0 0 16px 0;\n}\n\n\n\n.pin-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n\n\n.group-header[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n\n\n.pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%] {\n cursor: grab;\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n\n.edit-controls[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n\n\n.pin-thumbnail[_ngcontent-%COMP%] {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n\n\n.pin-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn[_ngcontent-%COMP%] {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.pin-info[_ngcontent-%COMP%] {\n padding: 10px 12px;\n}\n\n.pin-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.pin-app-badge[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n\n\n.add-pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n}\n\n.add-pin-card[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n\n\n\n\n.pin-context-menu[_ngcontent-%COMP%] {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: _ngcontent-%COMP%_pinMenuIn 0.15s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item[_ngcontent-%COMP%] {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n\n\n.slide-panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n.search-box[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.group-selector[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n\n\n.panel-results[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.panel-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n}\n\n.panel-section-title.collapsible[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n transition: color var(--mj-transition-base);\n}\n\n.panel-section-title.collapsible[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.section-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.panel-count[_ngcontent-%COMP%] {\n margin-left: auto;\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.panel-app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header[_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%] {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n\n\n.new-group-row[_ngcontent-%COMP%] {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.panel-item-action[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\n}\n\n\n\n\n\n\n\n\n\n@media (max-width: 1200px) {\n .quick-access-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 280px;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n\n\n@media (max-width: 992px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-3xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .home-dashboard[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \n\n overflow: visible;\n }\n\n .home-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 60px; \n\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; \n\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 99;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .pin-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}"], changeDetection: 0 });
2348
+ } }, dependencies: [i3.NgSelectOption, i3.ɵNgSelectMultipleOption, i3.DefaultValueAccessor, i3.SelectControlValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective, i5.LoadingComponent, i6.UserAppConfigComponent, i7.SlicePipe], styles: [".home-dashboard[_ngcontent-%COMP%] {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n\n\n.main-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 320px;\n}\n\n\n\n.home-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n\n\n.sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n\n\n.apps-section[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n\n\n.apps-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n\n\n.app-card[_ngcontent-%COMP%] {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card[_ngcontent-%COMP%]:hover::before {\n opacity: 1;\n}\n\n\n\n.app-icon-wrapper[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.app-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] {\n background: var(--app-color);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n\n\n.app-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.app-name[_ngcontent-%COMP%] {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description[_ngcontent-%COMP%] {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n\n\n.nav-preview[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n\n\n.app-arrow[_ngcontent-%COMP%] {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card[_ngcontent-%COMP%]:hover .app-arrow[_ngcontent-%COMP%] {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\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: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state[_ngcontent-%COMP%] button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 8px;\n}\n\n\n\n\n\n.quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open[_ngcontent-%COMP%] .quick-access-sidebar[_ngcontent-%COMP%] {\n transform: translateX(0);\n}\n\n.sidebar-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n\n\n.sidebar-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.sidebar-section[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n}\n\n.recents-section[_ngcontent-%COMP%] .sidebar-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.section-badge[_ngcontent-%COMP%] {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n\n\n.sidebar-items[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] {\n background: var(--mj-color-info-50);\n}\n\n.recent-item[_ngcontent-%COMP%] .sidebar-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n\n\n\n\n.pinned-section[_ngcontent-%COMP%] {\n margin-bottom: 32px;\n}\n\n.pinned-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header[_ngcontent-%COMP%] .section-title[_ngcontent-%COMP%] {\n margin: 0;\n}\n\n.pinned-actions[_ngcontent-%COMP%] {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn[_ngcontent-%COMP%] {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done[_ngcontent-%COMP%] {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n\n\n.edit-mode-banner[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner[_ngcontent-%COMP%] strong[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n.pin-empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 40px;\n color: var(--mj-text-disabled);\n margin-bottom: 16px;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n margin: 0 0 6px 0;\n}\n\n.pin-empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 360px;\n margin: 0 0 16px 0;\n}\n\n\n\n.pin-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n\n\n.group-header[_ngcontent-%COMP%] {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line[_ngcontent-%COMP%] {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn[_ngcontent-%COMP%] {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n\n\n.pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%] {\n cursor: grab;\n}\n\n.pin-card.edit-mode[_ngcontent-%COMP%]:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging[_ngcontent-%COMP%] {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n\n\n.edit-controls[_ngcontent-%COMP%] {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls[_ngcontent-%COMP%] > *[_ngcontent-%COMP%] {\n pointer-events: auto;\n}\n\n.drag-handle[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn[_ngcontent-%COMP%] {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n\n\n.pin-thumbnail[_ngcontent-%COMP%] {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail[_ngcontent-%COMP%] img[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n\n\n.pin-overlay[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-overlay[_ngcontent-%COMP%] {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn[_ngcontent-%COMP%] {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n\n\n.pin-info[_ngcontent-%COMP%] {\n padding: 10px 12px;\n}\n\n.pin-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.pin-card[_ngcontent-%COMP%]:hover .pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%] {\n opacity: 1;\n}\n\n.pin-name[_ngcontent-%COMP%] .more-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n.pin-app-badge[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n\n\n.add-pin-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n}\n\n.add-pin-card[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n\n\n\n\n.pin-context-menu[_ngcontent-%COMP%] {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: _ngcontent-%COMP%_pinMenuIn 0.15s ease;\n}\n\n@keyframes _ngcontent-%COMP%_pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header[_ngcontent-%COMP%]:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item[_ngcontent-%COMP%] {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider[_ngcontent-%COMP%] {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n\n\n\n\n.slide-panel-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 0.3s ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close[_ngcontent-%COMP%] {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n\n\n.search-box[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%]:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%] {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper[_ngcontent-%COMP%] input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-disabled);\n}\n\n\n\n.group-selector[_ngcontent-%COMP%] {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector[_ngcontent-%COMP%] select[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n\n\n.panel-results[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section[_ngcontent-%COMP%] {\n margin-bottom: 20px;\n}\n\n.panel-section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%]:first-child {\n font-size: 12px;\n}\n\n.panel-section-title.collapsible[_ngcontent-%COMP%] {\n cursor: pointer;\n user-select: none;\n transition: color var(--mj-transition-base);\n}\n\n.panel-section-title.collapsible[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-secondary);\n}\n\n.section-chevron[_ngcontent-%COMP%] {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.panel-count[_ngcontent-%COMP%] {\n margin-left: auto;\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n\n\n.panel-app-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header[_ngcontent-%COMP%]:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%] {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item[_ngcontent-%COMP%]:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n\n\n.new-group-row[_ngcontent-%COMP%] {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n.panel-item-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.panel-item-action[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\n}\n\n\n\n\n\n\n\n\n\n@media (max-width: 1200px) {\n .quick-access-sidebar[_ngcontent-%COMP%] {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 280px;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n\n\n@media (max-width: 992px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-3xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%] .main-content[_ngcontent-%COMP%] {\n margin-right: 0;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n\n\n@media (max-width: 768px) {\n .home-dashboard[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content[_ngcontent-%COMP%] {\n padding: 20px;\n padding-bottom: 100px; \n\n overflow: visible;\n }\n\n .home-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-2xl);\n }\n\n \n\n .quick-access-sidebar[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::before {\n display: none;\n }\n\n \n\n .home-dashboard.sidebar-open[_ngcontent-%COMP%]::after {\n display: none;\n }\n\n .pin-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .apps-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .app-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n }\n\n .app-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: var(--mj-text-lg);\n }\n\n .app-name[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview[_ngcontent-%COMP%] {\n display: none;\n }\n\n \n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content[_ngcontent-%COMP%] {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section[_ngcontent-%COMP%] .date[_ngcontent-%COMP%] {\n font-size: var(--mj-text-sm);\n }\n\n .section-title[_ngcontent-%COMP%] {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle[_ngcontent-%COMP%] {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}"], changeDetection: 0 });
2349
2349
  };
2350
2350
  HomeDashboardComponent = __decorate([
2351
2351
  RegisterClass(BaseResourceComponent, 'HomeDashboard')
@@ -2353,7 +2353,7 @@ HomeDashboardComponent = __decorate([
2353
2353
  export { HomeDashboardComponent };
2354
2354
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HomeDashboardComponent, [{
2355
2355
  type: Component,
2356
- args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Pinned Section -->\n @if (!isLoading) {\n <div class=\"pinned-section\">\n <div class=\"pinned-header\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n Pinned\n </h2>\n <div class=\"pinned-actions\">\n @if (EditMode) {\n <button class=\"pin-action-btn done\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-check\"></i> Done\n </button>\n } @else {\n <button class=\"pin-action-btn primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add Pin\n </button>\n @if (PinnedItems.length > 0) {\n <button class=\"pin-action-btn\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n }\n }\n </div>\n </div>\n\n @if (EditMode) {\n <div class=\"edit-mode-banner\">\n <i class=\"fa-solid fa-arrows-up-down-left-right\"></i>\n <span><strong>Edit mode</strong> \u2014 Drag cards to reorder. Click names to rename.</span>\n </div>\n }\n\n <!-- Empty State -->\n @if (PinnedItems.length === 0 && !EditMode) {\n <div class=\"pin-empty-state\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n <h3>No pinned items yet</h3>\n <p>Pin your favorite dashboards, views, queries, and reports for quick access.</p>\n <button class=\"pin-action-btn primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add your first pin\n </button>\n </div>\n }\n\n <!-- Pin Grid -->\n @if (PinnedItems.length > 0) {\n <div class=\"pin-grid\">\n <!-- Ungrouped Pins -->\n @for (pin of UngroupedPins; track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n <!-- Edit mode controls -->\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Thumbnail / Icon -->\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <!-- Pin Info -->\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (keydown.enter)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" (click)=\"ShowPinMenu($event, pin)\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName && pin.ResourceType !== 'Custom') {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Grouped Pins -->\n @for (group of PinGroups; track trackByGroup($index, group)) {\n <!-- Group Header -->\n <div class=\"group-header\">\n @if (EditMode && EditingGroupName === group) {\n <input class=\"group-name-input\"\n [value]=\"group\"\n (blur)=\"SaveGroupName(group, GetInputValue($event))\"\n (keydown.enter)=\"SaveGroupName(group, GetInputValue($event))\" />\n } @else {\n <span class=\"group-name\" (click)=\"EditMode ? StartEditingGroup(group) : null\">{{ group }}</span>\n }\n <div class=\"group-line\"></div>\n <span class=\"group-count\">{{ GetPinsInGroup(group).length }} pins</span>\n @if (EditMode) {\n <div class=\"group-edit-controls\">\n <button class=\"group-edit-btn danger\" (click)=\"RemoveGroup(group)\">\n <i class=\"fa-solid fa-folder-minus\"></i> Remove Group\n </button>\n </div>\n }\n </div>\n\n <!-- Pins in Group -->\n @for (pin of GetPinsInGroup(group); track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, $event.target.value)\"\n (keydown.enter)=\"SavePinName(pin.Id, $event.target.value)\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName) {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n }\n\n <!-- Add Pin card (edit mode) -->\n @if (EditMode) {\n <div class=\"add-pin-card\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Pin</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Pin Context Menu (ellipsis) -->\n @if (PinMenuVisible && PinMenuPin) {\n <div class=\"pin-context-menu\"\n [style.left.px]=\"PinMenuX\"\n [style.top.px]=\"PinMenuY\">\n <div class=\"pin-context-item\" (click)=\"OnPinMenuEdit()\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit</span>\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-submenu\">\n <div class=\"pin-context-item submenu-header\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>Move to Group</span>\n </div>\n @if (PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(undefined)\">\n <span>(No group)</span>\n </div>\n }\n @for (group of PinGroups; track group) {\n @if (group !== PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(group)\">\n <span>{{ group }}</span>\n </div>\n }\n }\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-item danger\" (click)=\"OnPinMenuUnpin()\">\n <i class=\"fa-solid fa-thumbtack-slash\"></i>\n <span>Unpin</span>\n </div>\n </div>\n }\n\n <!-- Add Pin Slide-In Panel -->\n @if (AddPanelOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"CloseAddPinPanel()\"></div>\n <div class=\"slide-panel\">\n <div class=\"slide-panel-header\">\n <h3><i class=\"fa-solid fa-thumbtack\"></i> Add Pin</h3>\n <button class=\"slide-panel-close\" (click)=\"CloseAddPinPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"search-box\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <input type=\"text\"\n placeholder=\"Search apps, dashboards, views, queries...\"\n [(ngModel)]=\"AddPanelSearchQuery\" />\n </div>\n </div>\n\n <div class=\"group-selector\">\n <label><i class=\"fa-solid fa-folder\"></i> Add to group:</label>\n <select [(ngModel)]=\"AddPanelSelectedGroup\">\n <option value=\"\">(No group)</option>\n @for (group of PinGroups; track group) {\n <option [value]=\"group\">{{ group }}</option>\n }\n <option value=\"__new__\">+ New group...</option>\n </select>\n </div>\n @if (AddPanelSelectedGroup === '__new__') {\n <div class=\"new-group-row\">\n <input class=\"new-group-input\"\n type=\"text\"\n placeholder=\"Enter new group name...\"\n [(ngModel)]=\"AddPanelNewGroupName\" />\n </div>\n }\n\n <div class=\"panel-results\">\n @if (AddPanelLoading) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading resources...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <!-- Apps with Nav Items -->\n @if (FilterApps().length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('apps')\">\n <i class=\"fa-solid fa-grid-2\"></i> Applications\n <span class=\"panel-count\">{{ FilterApps().length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['apps']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['apps']\"></i>\n </div>\n @if (!PanelSectionCollapsed['apps']) {\n @for (app of FilterApps(); track app.appId) {\n <div class=\"panel-app-header\" [style.--panel-app-color]=\"app.color\">\n <div class=\"panel-app-icon\">\n <i [class]=\"app.icon\"></i>\n </div>\n <span class=\"panel-app-name\">{{ app.appName }}</span>\n </div>\n @for (ni of app.navItems; track ni.label) {\n <div class=\"panel-item panel-nav-item\">\n <div class=\"panel-item-icon\" [style.background]=\"'color-mix(in srgb, ' + app.color + ' 10%, var(--mj-bg-surface-card))'\">\n <i [class]=\"ni.icon\" [style.color]=\"app.color\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ ni.label }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (ni.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinAppNavItem(app.appName, app.icon, app.color, ni.label, ni.icon)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n }\n\n <!-- Dashboards (metadata-driven Config type only) -->\n @if (FilterPanelItems(AvailableDashboards).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('dashboards')\">\n <i class=\"fa-solid fa-gauge-high\"></i> Dashboards\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableDashboards).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['dashboards']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['dashboards']\"></i>\n </div>\n @if (!PanelSectionCollapsed['dashboards']) {\n @for (item of FilterPanelItems(AvailableDashboards); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-gauge-high\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Dashboards', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Views -->\n @if (FilterPanelItems(AvailableViews).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('views')\">\n <i class=\"fa-solid fa-table-list\"></i> Views\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableViews).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['views']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['views']\"></i>\n </div>\n @if (!PanelSectionCollapsed['views']) {\n @for (item of FilterPanelItems(AvailableViews); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-table-list\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n <div class=\"panel-item-sub\">{{ item.entityName }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('User Views', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Queries -->\n @if (FilterPanelItems(AvailableQueries).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('queries')\">\n <i class=\"fa-solid fa-database\"></i> Queries\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableQueries).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['queries']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['queries']\"></i>\n </div>\n @if (!PanelSectionCollapsed['queries']) {\n @for (item of FilterPanelItems(AvailableQueries); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-database\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Queries', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n }\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n My Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button mjButton\n variant=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(favorite.Entity)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ getFavoriteDisplayName(favorite) }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(item.entityName)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: fixed;\n top: 80px; /* Below shell header with some spacing */\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title i {\n color: var(--mj-text-muted);\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section .sidebar-section-title i {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section .sidebar-section-title i {\n color: var(--mj-status-warning);\n}\n\n.recents-section .sidebar-section-title i {\n color: var(--mj-brand-primary);\n}\n\n.section-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item .sidebar-item-icon i {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item .sidebar-item-icon i {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item .sidebar-item-icon {\n background: var(--mj-color-info-50);\n}\n\n.recent-item .sidebar-item-icon i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty i {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n/* ========================================\n PINNED SECTION\n ======================================== */\n.pinned-section {\n margin-bottom: 32px;\n}\n\n.pinned-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header .section-title {\n margin: 0;\n}\n\n.pinned-actions {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n/* Edit Mode Banner */\n.edit-mode-banner {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner strong {\n color: var(--mj-brand-primary);\n}\n\n/* Pin Empty State */\n.pin-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.pin-empty-state > i {\n font-size: 40px;\n color: var(--mj-text-disabled);\n margin-bottom: 16px;\n}\n\n.pin-empty-state h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n margin: 0 0 6px 0;\n}\n\n.pin-empty-state p {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 360px;\n margin: 0 0 16px 0;\n}\n\n/* Pin Grid */\n.pin-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n/* Group Header */\n.group-header {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n/* Pin Card */\n.pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode {\n cursor: grab;\n}\n\n.pin-card.edit-mode:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Edit controls overlay */\n.edit-controls {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls > * {\n pointer-events: auto;\n}\n\n.drag-handle {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n/* Pin Thumbnail */\n.pin-thumbnail {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode > i {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n/* Hover overlay */\n.pin-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card:hover .pin-overlay {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n/* Pin Info */\n.pin-info {\n padding: 10px 12px;\n}\n\n.pin-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name .more-btn {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.pin-card:hover .pin-name .more-btn {\n opacity: 1;\n}\n\n.pin-name .more-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta > i {\n font-size: 10px;\n}\n\n.pin-app-badge {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n/* Add Pin Card */\n.add-pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card i {\n font-size: 28px;\n}\n\n.add-pin-card span {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n/* ========================================\n PIN CONTEXT MENU (ELLIPSIS)\n ======================================== */\n.pin-context-menu {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: pinMenuIn 0.15s ease;\n}\n\n@keyframes pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item i {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger i {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* ========================================\n SLIDE-IN PANEL (Add Pin)\n ======================================== */\n.slide-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel {\n position: fixed;\n top: 60px;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.3s ease;\n}\n\n@keyframes slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Search box */\n.search-box {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Group selector */\n.group-selector {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector label {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector select {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n/* Panel results */\n.panel-results {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section {\n margin-bottom: 20px;\n}\n\n.panel-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-section-title i:first-child {\n font-size: 12px;\n}\n\n.panel-section-title.collapsible {\n cursor: pointer;\n user-select: none;\n transition: color var(--mj-transition-base);\n}\n\n.panel-section-title.collapsible:hover {\n color: var(--mj-text-secondary);\n}\n\n.section-chevron {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.panel-count {\n margin-left: auto;\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n/* App hierarchy in panel */\n.panel-app-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon i {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Nav items under app \u2014 indented with left border accent */\n.panel-item.panel-nav-item {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n/* New group row */\n.new-group-row {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon i {\n font-size: 14px;\n}\n\n.panel-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action {\n flex-shrink: 0;\n}\n\n.panel-item-action button {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-3xl);\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below shell header */\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-2xl);\n }\n\n /* Full-width sidebar on mobile - positioned below top nav */\n .quick-access-sidebar {\n position: fixed;\n top: 60px; /* Below the shell header */\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 100; /* Below shell header */\n border-left: none;\n border-top: 1px solid var(--mj-border-default);\n }\n\n /* Add backdrop on mobile when sidebar is open */\n .home-dashboard.sidebar-open::before {\n content: '';\n position: fixed;\n top: 60px;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 99;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .pin-grid {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel {\n width: 100%;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: var(--mj-text-lg);\n }\n\n .app-name {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile */\n .sidebar-fab-toggle {\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section .date {\n font-size: var(--mj-text-sm);\n }\n\n .section-title {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
2356
+ args: [{ standalone: false, selector: 'mj-home-dashboard', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"home-dashboard\" [class.sidebar-open]=\"sidebarOpen && hasSidebarContent\">\n <!-- Main Content Area -->\n <div class=\"main-content\">\n <!-- Header Section -->\n <div class=\"home-header\">\n <div class=\"greeting-section\">\n <h1>{{ greeting }}, {{ currentUser?.Name }}</h1>\n <p class=\"date\">{{ formattedDate }}</p>\n </div>\n </div>\n\n <!-- Pinned Section -->\n @if (!isLoading) {\n <div class=\"pinned-section\">\n <div class=\"pinned-header\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n Pinned\n </h2>\n <div class=\"pinned-actions\">\n @if (EditMode) {\n <button class=\"pin-action-btn done\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-check\"></i> Done\n </button>\n } @else {\n <button class=\"pin-action-btn primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add Pin\n </button>\n @if (PinnedItems.length > 0) {\n <button class=\"pin-action-btn\" (click)=\"ToggleEditMode()\">\n <i class=\"fa-solid fa-pen\"></i> Edit\n </button>\n }\n }\n </div>\n </div>\n\n @if (EditMode) {\n <div class=\"edit-mode-banner\">\n <i class=\"fa-solid fa-arrows-up-down-left-right\"></i>\n <span><strong>Edit mode</strong> \u2014 Drag cards to reorder. Click names to rename.</span>\n </div>\n }\n\n <!-- Empty State -->\n @if (PinnedItems.length === 0 && !EditMode) {\n <div class=\"pin-empty-state\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n <h3>No pinned items yet</h3>\n <p>Pin your favorite dashboards, views, queries, and reports for quick access.</p>\n <button class=\"pin-action-btn primary\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i> Add your first pin\n </button>\n </div>\n }\n\n <!-- Pin Grid -->\n @if (PinnedItems.length > 0) {\n <div class=\"pin-grid\">\n <!-- Ungrouped Pins -->\n @for (pin of UngroupedPins; track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n <!-- Edit mode controls -->\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Thumbnail / Icon -->\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <!-- Pin Info -->\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (keydown.enter)=\"SavePinName(pin.Id, GetInputValue($event))\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" (click)=\"ShowPinMenu($event, pin)\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName && pin.ResourceType !== 'Custom') {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n\n <!-- Grouped Pins -->\n @for (group of PinGroups; track trackByGroup($index, group)) {\n <!-- Group Header -->\n <div class=\"group-header\">\n @if (EditMode && EditingGroupName === group) {\n <input class=\"group-name-input\"\n [value]=\"group\"\n (blur)=\"SaveGroupName(group, GetInputValue($event))\"\n (keydown.enter)=\"SaveGroupName(group, GetInputValue($event))\" />\n } @else {\n <span class=\"group-name\" (click)=\"EditMode ? StartEditingGroup(group) : null\">{{ group }}</span>\n }\n <div class=\"group-line\"></div>\n <span class=\"group-count\">{{ GetPinsInGroup(group).length }} pins</span>\n @if (EditMode) {\n <div class=\"group-edit-controls\">\n <button class=\"group-edit-btn danger\" (click)=\"RemoveGroup(group)\">\n <i class=\"fa-solid fa-folder-minus\"></i> Remove Group\n </button>\n </div>\n }\n </div>\n\n <!-- Pins in Group -->\n @for (pin of GetPinsInGroup(group); track trackByPin($index, pin)) {\n <div class=\"pin-card\"\n [class.edit-mode]=\"EditMode\"\n [class.dragging]=\"DraggingPinId === pin.Id\"\n [class.drag-over]=\"DragOverPinId === pin.Id\"\n [draggable]=\"EditMode\"\n (dragstart)=\"OnDragStart($event, pin)\"\n (dragover)=\"OnDragOver($event, pin)\"\n (dragleave)=\"OnDragLeave()\"\n (drop)=\"OnDrop($event, pin)\"\n (dragend)=\"OnDragEnd()\"\n (click)=\"OnPinClick(pin)\">\n\n @if (EditMode) {\n <div class=\"edit-controls\">\n <div class=\"drag-handle\"><i class=\"fa-solid fa-grip-vertical\"></i></div>\n <div class=\"edit-card-actions\">\n <button class=\"edit-card-btn delete\" (click)=\"RemovePin(pin.Id); $event.stopPropagation()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n </div>\n }\n\n @if (pin.Thumbnail) {\n <div class=\"pin-thumbnail\">\n <img [src]=\"pin.Thumbnail\" [alt]=\"pin.DisplayName\" />\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n } @else {\n <div class=\"pin-thumbnail icon-mode\" [style.--pin-icon-color]=\"pin.Color || 'var(--mj-text-muted)'\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n @if (!EditMode) {\n <div class=\"pin-overlay\">\n <button class=\"open-btn\" (click)=\"OnPinClick(pin); $event.stopPropagation()\">Open</button>\n </div>\n }\n </div>\n }\n\n <div class=\"pin-info\">\n @if (EditMode && EditingPinId === pin.Id) {\n <input class=\"pin-name-input\"\n [value]=\"pin.DisplayName\"\n (blur)=\"SavePinName(pin.Id, $event.target.value)\"\n (keydown.enter)=\"SavePinName(pin.Id, $event.target.value)\"\n (click)=\"$event.stopPropagation()\" />\n } @else {\n <div class=\"pin-name\" (click)=\"EditMode ? StartEditingPin(pin.Id, $event) : null\">\n {{ pin.DisplayName }}\n @if (!EditMode) {\n <button class=\"more-btn\" (click)=\"$event.stopPropagation()\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n </button>\n }\n </div>\n }\n <div class=\"pin-meta\">\n <i [class]=\"GetPinIcon(pin)\"></i>\n {{ GetResourceTypeLabel(pin) }}\n @if (pin.ApplicationName) {\n <span class=\"pin-app-badge\">{{ pin.ApplicationName }}</span>\n }\n </div>\n </div>\n </div>\n }\n }\n\n <!-- Add Pin card (edit mode) -->\n @if (EditMode) {\n <div class=\"add-pin-card\" (click)=\"OpenAddPinPanel()\">\n <i class=\"fa-solid fa-plus\"></i>\n <span>Add Pin</span>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- Pin Context Menu (ellipsis) -->\n @if (PinMenuVisible && PinMenuPin) {\n <div class=\"pin-context-menu\"\n [style.left.px]=\"PinMenuX\"\n [style.top.px]=\"PinMenuY\">\n <div class=\"pin-context-item\" (click)=\"OnPinMenuEdit()\">\n <i class=\"fa-solid fa-pen\"></i>\n <span>Edit</span>\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-submenu\">\n <div class=\"pin-context-item submenu-header\">\n <i class=\"fa-solid fa-folder\"></i>\n <span>Move to Group</span>\n </div>\n @if (PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(undefined)\">\n <span>(No group)</span>\n </div>\n }\n @for (group of PinGroups; track group) {\n @if (group !== PinMenuPin.Group) {\n <div class=\"pin-context-item submenu-item\" (click)=\"OnPinMenuMoveToGroup(group)\">\n <span>{{ group }}</span>\n </div>\n }\n }\n </div>\n <div class=\"pin-context-divider\"></div>\n <div class=\"pin-context-item danger\" (click)=\"OnPinMenuUnpin()\">\n <i class=\"fa-solid fa-thumbtack-slash\"></i>\n <span>Unpin</span>\n </div>\n </div>\n }\n\n <!-- Add Pin Slide-In Panel -->\n @if (AddPanelOpen) {\n <div class=\"slide-panel-backdrop\" (click)=\"CloseAddPinPanel()\"></div>\n <div class=\"slide-panel\">\n <div class=\"slide-panel-header\">\n <h3><i class=\"fa-solid fa-thumbtack\"></i> Add Pin</h3>\n <button class=\"slide-panel-close\" (click)=\"CloseAddPinPanel()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <div class=\"search-box\">\n <div class=\"search-input-wrapper\">\n <i class=\"fa-solid fa-magnifying-glass\"></i>\n <input type=\"text\"\n placeholder=\"Search apps, dashboards, views, queries...\"\n [(ngModel)]=\"AddPanelSearchQuery\" />\n </div>\n </div>\n\n <div class=\"group-selector\">\n <label><i class=\"fa-solid fa-folder\"></i> Add to group:</label>\n <select [(ngModel)]=\"AddPanelSelectedGroup\">\n <option value=\"\">(No group)</option>\n @for (group of PinGroups; track group) {\n <option [value]=\"group\">{{ group }}</option>\n }\n <option value=\"__new__\">+ New group...</option>\n </select>\n </div>\n @if (AddPanelSelectedGroup === '__new__') {\n <div class=\"new-group-row\">\n <input class=\"new-group-input\"\n type=\"text\"\n placeholder=\"Enter new group name...\"\n [(ngModel)]=\"AddPanelNewGroupName\" />\n </div>\n }\n\n <div class=\"panel-results\">\n @if (AddPanelLoading) {\n <div class=\"panel-loading\">\n <mj-loading text=\"Loading resources...\" size=\"small\"></mj-loading>\n </div>\n } @else {\n <!-- Apps with Nav Items -->\n @if (FilterApps().length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('apps')\">\n <i class=\"fa-solid fa-grid-2\"></i> Applications\n <span class=\"panel-count\">{{ FilterApps().length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['apps']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['apps']\"></i>\n </div>\n @if (!PanelSectionCollapsed['apps']) {\n @for (app of FilterApps(); track app.appId) {\n <div class=\"panel-app-header\" [style.--panel-app-color]=\"app.color\">\n <div class=\"panel-app-icon\">\n <i [class]=\"app.icon\"></i>\n </div>\n <span class=\"panel-app-name\">{{ app.appName }}</span>\n </div>\n @for (ni of app.navItems; track ni.label) {\n <div class=\"panel-item panel-nav-item\">\n <div class=\"panel-item-icon\" [style.background]=\"'color-mix(in srgb, ' + app.color + ' 10%, var(--mj-bg-surface-card))'\">\n <i [class]=\"ni.icon\" [style.color]=\"app.color\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ ni.label }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (ni.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinAppNavItem(app.appName, app.icon, app.color, ni.label, ni.icon)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n }\n\n <!-- Dashboards (metadata-driven Config type only) -->\n @if (FilterPanelItems(AvailableDashboards).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('dashboards')\">\n <i class=\"fa-solid fa-gauge-high\"></i> Dashboards\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableDashboards).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['dashboards']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['dashboards']\"></i>\n </div>\n @if (!PanelSectionCollapsed['dashboards']) {\n @for (item of FilterPanelItems(AvailableDashboards); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-gauge-high\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Dashboards', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Views -->\n @if (FilterPanelItems(AvailableViews).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('views')\">\n <i class=\"fa-solid fa-table-list\"></i> Views\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableViews).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['views']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['views']\"></i>\n </div>\n @if (!PanelSectionCollapsed['views']) {\n @for (item of FilterPanelItems(AvailableViews); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-table-list\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n <div class=\"panel-item-sub\">{{ item.entityName }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('User Views', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n\n <!-- Queries -->\n @if (FilterPanelItems(AvailableQueries).length > 0) {\n <div class=\"panel-section\">\n <div class=\"panel-section-title collapsible\" (click)=\"TogglePanelSection('queries')\">\n <i class=\"fa-solid fa-database\"></i> Queries\n <span class=\"panel-count\">{{ FilterPanelItems(AvailableQueries).length }}</span>\n <i class=\"section-chevron fa-solid\" [class.fa-chevron-down]=\"!PanelSectionCollapsed['queries']\" [class.fa-chevron-right]=\"PanelSectionCollapsed['queries']\"></i>\n </div>\n @if (!PanelSectionCollapsed['queries']) {\n @for (item of FilterPanelItems(AvailableQueries); track item.id) {\n <div class=\"panel-item\">\n <div class=\"panel-item-icon\" style=\"background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface-card))\">\n <i class=\"fa-solid fa-database\" style=\"color: var(--mj-brand-primary)\"></i>\n </div>\n <div class=\"panel-item-info\">\n <div class=\"panel-item-name\">{{ item.name }}</div>\n </div>\n <div class=\"panel-item-action\">\n @if (item.pinned) {\n <button class=\"pinned-badge\"><i class=\"fa-solid fa-check\"></i> Pinned</button>\n } @else {\n <button class=\"pin-btn\" (click)=\"PinFromPanel('Queries', item.id, item.name)\">\n <i class=\"fa-solid fa-plus\"></i> Pin\n </button>\n }\n </div>\n </div>\n }\n }\n </div>\n }\n }\n </div>\n </div>\n }\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading your applications...\" size=\"large\"></mj-loading>\n </div>\n }\n\n <!-- Apps Grid -->\n @if (!isLoading) {\n <div class=\"apps-section\">\n <h2 class=\"section-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n My Applications\n </h2>\n <div class=\"apps-grid\">\n @for (appData of appsDisplayData; track trackByApp($index, appData)) {\n <div\n class=\"app-card\"\n [style.--app-color]=\"appData.color\"\n (click)=\"onAppClick(appData.app)\">\n <!-- App Icon -->\n <div class=\"app-icon-wrapper\">\n <div class=\"app-icon\">\n <i [class]=\"appData.icon\"></i>\n </div>\n </div>\n <!-- App Info -->\n <div class=\"app-info\">\n <h3 class=\"app-name\">{{ appData.app.Name }}</h3>\n @if (appData.app.Description) {\n <p class=\"app-description\">{{ appData.app.Description }}</p>\n }\n <!-- Nav Items Preview -->\n @if (appData.navItemsCount > 0) {\n <div class=\"nav-preview\">\n @for (item of appData.navItemsPreview; track trackByNavItem($index, item)) {\n <div class=\"nav-item-chip\">\n <i [class]=\"item.Icon\"></i>\n <span>{{ item.Label }}</span>\n </div>\n }\n @if (appData.showMoreItems) {\n <span class=\"more-items\">\n +{{ appData.moreItemsCount }} more\n </span>\n }\n </div>\n }\n </div>\n <!-- Hover Arrow -->\n <div class=\"app-arrow\">\n <i class=\"fa-solid fa-arrow-right\"></i>\n </div>\n </div>\n }\n </div>\n <!-- Empty State -->\n @if (apps.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-folder-open\"></i>\n </div>\n <h3>No Applications Available</h3>\n <p>You don't have any applications configured yet.</p>\n <button mjButton\n variant=\"primary\"\n (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n Configure Applications\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Collapsible Right Sidebar -->\n @if (hasSidebarContent) {\n <div class=\"quick-access-sidebar\">\n <div class=\"sidebar-header\">\n <h3>\n <i class=\"fa-solid fa-bolt\"></i>\n Quick Access\n </h3>\n <button class=\"sidebar-close-btn\" (click)=\"toggleSidebar()\" title=\"Close panel\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n <div class=\"sidebar-content\">\n <!-- Unread Notifications Section -->\n @if (unreadNotifications.length > 0) {\n <div class=\"sidebar-section notifications-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-bell\"></i>\n Notifications\n <span class=\"section-badge\">{{ unreadNotifications.length }}</span>\n </h4>\n <div class=\"sidebar-items\">\n @for (notification of unreadNotifications; track trackByNotification($index, notification)) {\n <div\n class=\"sidebar-item notification-item\"\n (click)=\"onNotificationClick(notification)\">\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ notification.Title }}</span>\n <span class=\"sidebar-item-subtitle\">{{ notification.Message | slice:0:40 }}{{ (notification.Message?.length || 0) > 40 ? '...' : '' }}</span>\n </div>\n </div>\n }\n </div>\n </div>\n }\n <!-- Favorites Section -->\n @if (favorites.length > 0 || favoritesLoading) {\n <div class=\"sidebar-section favorites-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-star\"></i>\n Favorites\n </h4>\n @if (!favoritesLoading) {\n <div class=\"sidebar-items\">\n @for (favorite of favorites; track trackByFavorite($index, favorite)) {\n <div\n class=\"sidebar-item favorite-item\"\n (click)=\"onFavoriteClick(favorite)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(favorite.Entity)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ getFavoriteDisplayName(favorite) }}</span>\n <span class=\"sidebar-item-subtitle\">{{ favorite.Entity }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (favoritesLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Recents Section -->\n @if (recentItems.length > 0 || recentsLoading) {\n <div class=\"sidebar-section recents-section\">\n <h4 class=\"sidebar-section-title\">\n <i class=\"fa-solid fa-clock-rotate-left\"></i>\n Recent\n </h4>\n @if (!recentsLoading) {\n <div class=\"sidebar-items\">\n @for (item of recentItems; track trackByRecent($index, item)) {\n <div\n class=\"sidebar-item recent-item\"\n (click)=\"onRecentClick(item)\">\n <div class=\"sidebar-item-icon\">\n <i [class]=\"getEntityIconByName(item.entityName)\"></i>\n </div>\n <div class=\"sidebar-item-info\">\n <span class=\"sidebar-item-title\">{{ item.recordName || item.recordId }}</span>\n <span class=\"sidebar-item-subtitle\">{{ item.entityName }} \u00B7 {{ formatDate(item.latestAt) }}</span>\n </div>\n </div>\n }\n </div>\n }\n @if (recentsLoading) {\n <div class=\"sidebar-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading...</span>\n </div>\n }\n </div>\n }\n <!-- Empty sidebar state -->\n @if (!favoritesLoading && !recentsLoading && unreadNotifications.length === 0 && favorites.length === 0 && recentItems.length === 0) {\n <div class=\"sidebar-empty\">\n <i class=\"fa-solid fa-inbox\"></i>\n <p>No quick access items</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Quick Access FAB Toggle (Fixed Button) -->\n @if (hasSidebarContent && !sidebarOpen) {\n <button class=\"sidebar-fab-toggle\"\n (click)=\"toggleSidebar()\"\n title=\"Quick Access\">\n <i class=\"fa-solid fa-bolt\"></i>\n @if (unreadNotifications.length > 0) {\n <span class=\"fab-badge\">{{ unreadNotifications.length }}</span>\n }\n </button>\n }\n\n <!-- App Configuration Dialog -->\n <mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n </mj-user-app-config>\n</div>\n", styles: [".home-dashboard {\n display: flex;\n height: 100%;\n background: var(--mj-bg-page);\n overflow: hidden;\n position: relative;\n}\n\n/* Main Content Area */\n.main-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n padding: 32px;\n overflow-y: auto;\n transition: margin-right var(--mj-transition-slow);\n}\n\n/* Sidebar open state adjusts main content on desktop */\n.home-dashboard.sidebar-open .main-content {\n margin-right: 320px;\n}\n\n/* Header */\n.home-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 32px;\n}\n\n.greeting-section h1 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-4xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.greeting-section .date {\n margin: 0;\n font-size: var(--mj-text-base);\n color: var(--mj-text-muted);\n}\n\n/* FAB Toggle Button for Quick Access - top-right on desktop */\n.sidebar-fab-toggle {\n position: absolute;\n top: 20px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: var(--mj-radius-full);\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xl);\n cursor: pointer;\n box-shadow: var(--mj-shadow-brand-md);\n transition: all var(--mj-transition-base);\n z-index: 100;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.sidebar-fab-toggle:hover {\n background: var(--mj-brand-primary-hover);\n transform: scale(1.05);\n box-shadow: 0 6px 16px color-mix(in srgb, var(--mj-brand-primary) 50%, transparent);\n}\n\n.fab-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 20px;\n height: 20px;\n padding: 0 6px;\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: var(--mj-text-xs);\n font-weight: var(--mj-font-semibold);\n border-radius: var(--mj-radius-full);\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Loading State */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n flex: 1;\n gap: 16px;\n color: var(--mj-text-muted);\n}\n\n.loading-spinner {\n font-size: var(--mj-text-4xl);\n color: var(--mj-brand-primary);\n}\n\n/* Apps Section */\n.apps-section {\n flex: 0 0 auto;\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 12px;\n margin: 0 0 24px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.section-title i {\n color: var(--mj-text-muted);\n}\n\n/* Apps Grid */\n.apps-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 20px;\n}\n\n/* App Card */\n.app-card {\n --app-color: var(--mj-text-muted);\n display: flex;\n align-items: flex-start;\n gap: 16px;\n padding: 20px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n overflow: hidden;\n}\n\n.app-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n width: 4px;\n height: 100%;\n background: var(--app-color);\n opacity: 0;\n transition: opacity 0.25s ease;\n}\n\n.app-card:hover {\n border-color: var(--app-color);\n box-shadow: var(--mj-shadow-lg);\n transform: translateY(-3px);\n}\n\n.app-card:hover::before {\n opacity: 1;\n}\n\n/* App Icon */\n.app-icon-wrapper {\n flex-shrink: 0;\n}\n\n.app-icon {\n width: 52px;\n height: 52px;\n border-radius: var(--mj-radius-lg);\n background: color-mix(in srgb, var(--app-color) 12%, transparent);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.25s ease;\n}\n\n.app-icon i {\n font-size: var(--mj-text-xl);\n color: var(--app-color);\n transition: transform 0.25s ease;\n}\n\n.app-card:hover .app-icon {\n background: var(--app-color);\n}\n\n.app-card:hover .app-icon i {\n color: var(--mj-text-inverse);\n transform: scale(1.1);\n}\n\n/* App Info */\n.app-info {\n flex: 1;\n min-width: 0;\n}\n\n.app-name {\n margin: 0 0 4px 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n}\n\n.app-description {\n margin: 0 0 10px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n line-height: var(--mj-leading-snug);\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n\n/* Nav Items Preview */\n.nav-preview {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n align-items: center;\n}\n\n.nav-item-chip {\n display: flex;\n align-items: center;\n gap: 5px;\n padding: 3px 8px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-xs);\n color: var(--mj-text-secondary);\n}\n\n.nav-item-chip i {\n font-size: 9px;\n color: var(--mj-text-muted);\n}\n\n.more-items {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n font-style: italic;\n}\n\n/* App Arrow */\n.app-arrow {\n position: absolute;\n right: 14px;\n top: 50%;\n transform: translateY(-50%) translateX(10px);\n opacity: 0;\n transition: all 0.25s ease;\n color: var(--app-color);\n font-size: var(--mj-text-base);\n}\n\n.app-card:hover .app-arrow {\n opacity: 1;\n transform: translateY(-50%) translateX(0);\n}\n\n/* Empty State */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 64px 24px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n border-radius: var(--mj-radius-full);\n background: var(--mj-bg-surface-card);\n display: flex;\n align-items: center;\n justify-content: center;\n margin-bottom: 24px;\n}\n\n.empty-icon i {\n font-size: var(--mj-text-4xl);\n color: var(--mj-text-disabled);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: var(--mj-text-xl);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n.empty-state p {\n margin: 0 0 20px 0;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 400px;\n}\n\n.empty-state button i {\n margin-right: 8px;\n}\n\n/* ========================================\n RIGHT SIDEBAR\n ======================================== */\n.quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n display: flex;\n flex-direction: column;\n transform: translateX(100%);\n transition: transform var(--mj-transition-slow);\n overflow: hidden;\n z-index: 100;\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 8%, transparent);\n}\n\n.home-dashboard.sidebar-open .quick-access-sidebar {\n transform: translateX(0);\n}\n\n.sidebar-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.sidebar-header h3 {\n margin: 0;\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.sidebar-header h3 i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-sm);\n}\n\n.sidebar-close-btn {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n.sidebar-content {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n}\n\n/* Sidebar Sections */\n.sidebar-section {\n margin-bottom: 20px;\n}\n\n.sidebar-section:last-child {\n margin-bottom: 0;\n}\n\n.sidebar-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 12px 0;\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.sidebar-section-title i {\n font-size: var(--mj-text-xs);\n}\n\n.notifications-section .sidebar-section-title i {\n color: var(--mj-color-warning-600);\n}\n\n.favorites-section .sidebar-section-title i {\n color: var(--mj-status-warning);\n}\n\n.recents-section .sidebar-section-title i {\n color: var(--mj-brand-primary);\n}\n\n.section-badge {\n background: var(--mj-status-error);\n color: var(--mj-text-inverse);\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n padding: 2px 6px;\n border-radius: var(--mj-radius-md);\n margin-left: auto;\n}\n\n/* Sidebar Items */\n.sidebar-items {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sidebar-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.sidebar-item:hover {\n background: var(--mj-bg-surface-hover);\n transform: translateX(4px);\n}\n\n.sidebar-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n background: var(--mj-bg-surface);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.sidebar-item-icon i {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n}\n\n.notification-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.notification-item .sidebar-item-icon i {\n color: var(--mj-color-warning-600);\n}\n\n.favorite-item .sidebar-item-icon {\n background: var(--mj-color-warning-50);\n}\n\n.favorite-item .sidebar-item-icon i {\n color: var(--mj-color-warning-500);\n}\n\n.recent-item .sidebar-item-icon {\n background: var(--mj-color-info-50);\n}\n\n.recent-item .sidebar-item-icon i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-item-info {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n flex: 1;\n}\n\n.sidebar-item-title {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-item-subtitle {\n font-size: var(--mj-text-xs);\n color: var(--mj-text-muted);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.sidebar-loading {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n padding: 8px 0;\n}\n\n.sidebar-loading i {\n color: var(--mj-brand-primary);\n}\n\n.sidebar-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px 20px;\n text-align: center;\n color: var(--mj-text-disabled);\n}\n\n.sidebar-empty i {\n font-size: var(--mj-text-4xl);\n margin-bottom: 12px;\n}\n\n.sidebar-empty p {\n margin: 0;\n font-size: var(--mj-text-sm);\n}\n\n\n/* ========================================\n PINNED SECTION\n ======================================== */\n.pinned-section {\n margin-bottom: 32px;\n}\n\n.pinned-header {\n display: flex;\n align-items: center;\n gap: 12px;\n margin-bottom: 20px;\n}\n\n.pinned-header .section-title {\n margin: 0;\n}\n\n.pinned-actions {\n margin-left: auto;\n display: flex;\n gap: 8px;\n}\n\n.pin-action-btn {\n padding: 6px 14px;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: all var(--mj-transition-base);\n}\n\n.pin-action-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n\n.pin-action-btn.primary:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pin-action-btn.done {\n background: var(--mj-status-success);\n color: var(--mj-text-inverse);\n border-color: var(--mj-status-success);\n}\n\n/* Edit Mode Banner */\n.edit-mode-banner {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\n border-radius: var(--mj-radius-lg);\n padding: 12px 20px;\n margin-bottom: 20px;\n display: flex;\n align-items: center;\n gap: 12px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.edit-mode-banner i {\n color: var(--mj-brand-primary);\n font-size: var(--mj-text-base);\n}\n\n.edit-mode-banner strong {\n color: var(--mj-brand-primary);\n}\n\n/* Pin Empty State */\n.pin-empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 40px 20px;\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-xl);\n border: 2px dashed var(--mj-border-default);\n text-align: center;\n}\n\n.pin-empty-state > i {\n font-size: 40px;\n color: var(--mj-text-disabled);\n margin-bottom: 16px;\n}\n\n.pin-empty-state h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n margin: 0 0 6px 0;\n}\n\n.pin-empty-state p {\n font-size: var(--mj-text-sm);\n color: var(--mj-text-muted);\n max-width: 360px;\n margin: 0 0 16px 0;\n}\n\n/* Pin Grid */\n.pin-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));\n gap: 16px;\n margin-bottom: 12px;\n}\n\n/* Group Header */\n.group-header {\n grid-column: 1 / -1;\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 8px 0 4px 0;\n margin-top: 8px;\n}\n\n.group-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.group-line {\n flex: 1;\n height: 1px;\n background: var(--mj-border-default);\n}\n\n.group-count {\n font-size: 11px;\n color: var(--mj-text-disabled);\n background: var(--mj-bg-surface-card);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.group-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 8px;\n background: var(--mj-bg-surface);\n outline: none;\n width: 160px;\n}\n\n.group-edit-controls {\n display: flex;\n gap: 6px;\n}\n\n.group-edit-btn {\n background: none;\n border: 1px solid transparent;\n color: var(--mj-text-muted);\n font-size: 11px;\n cursor: pointer;\n padding: 2px 8px;\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n gap: 4px;\n transition: all var(--mj-transition-base);\n}\n\n.group-edit-btn:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-border-default);\n color: var(--mj-text-secondary);\n}\n\n.group-edit-btn.danger:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n/* Pin Card */\n.pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n overflow: hidden;\n cursor: pointer;\n transition: all 0.25s ease;\n position: relative;\n}\n\n.pin-card:hover {\n border-color: color-mix(in srgb, var(--mj-brand-primary) 40%, var(--mj-border-default));\n box-shadow: var(--mj-shadow-md);\n transform: translateY(-2px);\n}\n\n.pin-card.edit-mode {\n cursor: grab;\n}\n\n.pin-card.edit-mode:active {\n cursor: grabbing;\n}\n\n.pin-card.dragging {\n opacity: 0.5;\n border-color: var(--mj-brand-primary);\n box-shadow: var(--mj-shadow-lg);\n transform: rotate(2deg);\n}\n\n.pin-card.drag-over {\n border-color: var(--mj-brand-primary);\n border-style: dashed;\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n}\n\n/* Edit controls overlay */\n.edit-controls {\n position: absolute;\n top: 8px;\n left: 8px;\n right: 8px;\n display: flex;\n justify-content: space-between;\n z-index: 10;\n pointer-events: none;\n}\n\n.edit-controls > * {\n pointer-events: auto;\n}\n\n.drag-handle {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 14px;\n cursor: grab;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.drag-handle:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-actions {\n display: flex;\n gap: 4px;\n}\n\n.edit-card-btn {\n width: 28px;\n height: 28px;\n background: color-mix(in srgb, var(--mj-bg-surface) 92%, transparent);\n border-radius: var(--mj-radius-sm);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-text-muted);\n font-size: 12px;\n cursor: pointer;\n box-shadow: var(--mj-shadow-sm);\n border: 1px solid var(--mj-border-subtle);\n transition: all var(--mj-transition-base);\n}\n\n.edit-card-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n box-shadow: var(--mj-shadow-md);\n}\n\n.edit-card-btn.delete:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n\n/* Pin Thumbnail */\n.pin-thumbnail {\n width: 100%;\n aspect-ratio: 16 / 10;\n overflow: hidden;\n position: relative;\n}\n\n.pin-thumbnail img {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.pin-thumbnail.icon-mode {\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--pin-icon-color, var(--mj-text-muted)) 10%, var(--mj-bg-surface-card));\n}\n\n.pin-thumbnail.icon-mode > i {\n font-size: 36px;\n color: var(--pin-icon-color, var(--mj-text-muted));\n opacity: 0.7;\n}\n\n/* Hover overlay */\n.pin-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n pointer-events: none;\n background: rgba(0,0,0,0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pin-card:hover .pin-overlay {\n opacity: 1;\n pointer-events: auto;\n}\n\n.open-btn {\n padding: 8px 20px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n border: none;\n border-radius: var(--mj-radius-md);\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n box-shadow: var(--mj-shadow-md);\n}\n\n/* Pin Info */\n.pin-info {\n padding: 10px 12px;\n}\n\n.pin-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n margin-bottom: 4px;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.pin-name .more-btn {\n margin-left: auto;\n opacity: 0;\n transition: opacity var(--mj-transition-base);\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n padding: 2px 4px;\n border-radius: 4px;\n font-size: 14px;\n}\n\n.pin-card:hover .pin-name .more-btn {\n opacity: 1;\n}\n\n.pin-name .more-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-name-input {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n padding: 2px 6px;\n width: 100%;\n outline: none;\n background: var(--mj-bg-surface);\n}\n\n.pin-meta {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.pin-meta > i {\n font-size: 10px;\n}\n\n.pin-app-badge {\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 10px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-secondary);\n}\n\n/* Add Pin Card */\n.add-pin-card {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-lg);\n border: 2px dashed var(--mj-border-default);\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 180px;\n cursor: pointer;\n transition: all var(--mj-transition-base);\n gap: 8px;\n color: var(--mj-text-muted);\n}\n\n.add-pin-card:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface));\n}\n\n.add-pin-card i {\n font-size: 28px;\n}\n\n.add-pin-card span {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-semibold);\n}\n\n/* ========================================\n PIN CONTEXT MENU (ELLIPSIS)\n ======================================== */\n.pin-context-menu {\n position: fixed;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n box-shadow: var(--mj-shadow-lg);\n min-width: 180px;\n z-index: 10001;\n overflow: hidden;\n animation: pinMenuIn 0.15s ease;\n}\n\n@keyframes pinMenuIn {\n from { opacity: 0; transform: scale(0.95); }\n to { opacity: 1; transform: scale(1); }\n}\n\n.pin-context-item {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 9px 14px;\n cursor: pointer;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n transition: background 0.15s;\n}\n\n.pin-context-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.pin-context-item i {\n width: 16px;\n text-align: center;\n color: var(--mj-text-secondary);\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-item.danger {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger i {\n color: var(--mj-status-error);\n}\n\n.pin-context-item.danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, var(--mj-bg-surface));\n}\n\n.pin-context-item.submenu-header {\n font-weight: var(--mj-font-medium);\n cursor: default;\n font-size: 12px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n padding: 6px 14px;\n}\n\n.pin-context-item.submenu-header:hover {\n background: transparent;\n}\n\n.pin-context-item.submenu-item {\n padding-left: 30px;\n font-size: var(--mj-text-sm);\n}\n\n.pin-context-divider {\n height: 1px;\n background: var(--mj-border-default);\n margin: 4px 0;\n}\n\n/* ========================================\n SLIDE-IN PANEL (Add Pin)\n ======================================== */\n.slide-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 2000;\n}\n\n.slide-panel {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 400px;\n background: var(--mj-bg-surface);\n border-left: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-xl);\n z-index: 2001;\n display: flex;\n flex-direction: column;\n animation: slideIn 0.3s ease;\n}\n\n@keyframes slideIn {\n from { transform: translateX(100%); }\n to { transform: translateX(0); }\n}\n\n.slide-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.slide-panel-header h3 {\n font-size: var(--mj-text-base);\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0;\n}\n\n.slide-panel-header h3 i {\n color: var(--mj-brand-primary);\n}\n\n.slide-panel-close {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-text-muted);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all var(--mj-transition-base);\n}\n\n.slide-panel-close:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Search box */\n.search-box {\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.search-input-wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n padding: 8px 12px;\n transition: all var(--mj-transition-base);\n}\n\n.search-input-wrapper:focus-within {\n border-color: var(--mj-border-focus);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 15%, transparent);\n}\n\n.search-input-wrapper i {\n color: var(--mj-text-muted);\n font-size: 14px;\n}\n\n.search-input-wrapper input {\n border: none;\n outline: none;\n background: transparent;\n font-size: 14px;\n color: var(--mj-text-primary);\n flex: 1;\n}\n\n.search-input-wrapper input::placeholder {\n color: var(--mj-text-disabled);\n}\n\n/* Group selector */\n.group-selector {\n padding: 12px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: var(--mj-text-sm);\n color: var(--mj-text-secondary);\n}\n\n.group-selector label {\n font-weight: var(--mj-font-medium);\n white-space: nowrap;\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.group-selector select {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n cursor: pointer;\n}\n\n.new-group-input {\n flex: 1;\n padding: 4px 8px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n/* Panel results */\n.panel-results {\n flex: 1;\n overflow-y: auto;\n padding: 16px 20px;\n}\n\n.panel-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n}\n\n.panel-section {\n margin-bottom: 20px;\n}\n\n.panel-section-title {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 10px;\n padding-bottom: 6px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-section-title i:first-child {\n font-size: 12px;\n}\n\n.panel-section-title.collapsible {\n cursor: pointer;\n user-select: none;\n transition: color var(--mj-transition-base);\n}\n\n.panel-section-title.collapsible:hover {\n color: var(--mj-text-secondary);\n}\n\n.section-chevron {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.panel-count {\n margin-left: auto;\n background: var(--mj-bg-surface-card);\n padding: 1px 6px;\n border-radius: 8px;\n font-size: 10px;\n color: var(--mj-text-disabled);\n}\n\n/* App hierarchy in panel */\n.panel-app-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px 6px 12px;\n margin-top: 8px;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.panel-app-header:first-child {\n margin-top: 0;\n}\n\n.panel-app-icon {\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-app-icon i {\n font-size: 14px;\n color: var(--panel-app-color);\n}\n\n.panel-app-name {\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.3px;\n}\n\n/* Nav items under app \u2014 indented with left border accent */\n.panel-item.panel-nav-item {\n padding: 10px 12px 10px 32px;\n margin-left: 12px;\n border-left: 2px solid var(--mj-border-subtle);\n}\n\n.panel-item.panel-nav-item:last-of-type {\n border-left-color: transparent;\n}\n\n.panel-item.panel-nav-item:hover {\n border-left-color: var(--mj-brand-primary);\n}\n\n/* New group row */\n.new-group-row {\n padding: 0 20px 12px 20px;\n}\n\n.new-group-input {\n width: 100%;\n padding: 6px 10px;\n border: 1px solid var(--mj-border-focus);\n border-radius: var(--mj-radius-sm);\n font-size: var(--mj-text-sm);\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n outline: none;\n}\n\n.panel-item {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n border-radius: var(--mj-radius-md);\n transition: all var(--mj-transition-base);\n cursor: pointer;\n}\n\n.panel-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.panel-item-icon {\n width: 36px;\n height: 36px;\n border-radius: var(--mj-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.panel-item-icon i {\n font-size: 14px;\n}\n\n.panel-item-info {\n flex: 1;\n min-width: 0;\n}\n\n.panel-item-name {\n font-size: var(--mj-text-sm);\n font-weight: var(--mj-font-medium);\n color: var(--mj-text-primary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.panel-item-sub {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.panel-item-action {\n flex-shrink: 0;\n}\n\n.panel-item-action button {\n padding: 4px 12px;\n border-radius: var(--mj-radius-sm);\n font-size: 12px;\n font-weight: var(--mj-font-semibold);\n cursor: pointer;\n transition: all var(--mj-transition-base);\n}\n\n.pin-btn {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: 1px solid var(--mj-brand-primary);\n}\n\n.pin-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.pinned-badge {\n background: transparent;\n color: var(--mj-status-success);\n border: 1px solid var(--mj-status-success);\n cursor: default !important;\n}\n\n\n/* ========================================\n RESPONSIVE DESIGN\n ======================================== */\n\n/* Tablet and smaller desktop */\n@media (max-width: 1200px) {\n .quick-access-sidebar {\n width: 280px;\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 280px;\n }\n\n .apps-grid {\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n }\n}\n\n/* Tablet */\n@media (max-width: 992px) {\n .main-content {\n padding: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-3xl);\n }\n\n /* Make sidebar an overlay on tablet */\n .quick-access-sidebar {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n width: 320px;\n z-index: 1000;\n box-shadow: -4px 0 20px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n }\n\n .home-dashboard.sidebar-open .main-content {\n margin-right: 0;\n }\n\n /* Show backdrop when sidebar is open on tablet */\n .home-dashboard.sidebar-open::after {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n right: 320px;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n }\n}\n\n/* Mobile */\n@media (max-width: 768px) {\n .home-dashboard {\n height: auto;\n min-height: 100%;\n overflow: visible;\n }\n\n .main-content {\n padding: 20px;\n padding-bottom: 100px; /* Space for FAB button */\n overflow: visible;\n }\n\n .home-header {\n flex-direction: column;\n gap: 16px;\n margin-bottom: 24px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-2xl);\n }\n\n /* Full-width sidebar on mobile \u2014 fixed overlay covering full viewport */\n .quick-access-sidebar {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 100%;\n max-width: 100%;\n z-index: 10000;\n border-left: none;\n border-top: none;\n }\n\n /* No separate backdrop needed on mobile \u2014 sidebar covers full screen */\n .home-dashboard.sidebar-open::before {\n display: none;\n }\n\n /* No ::after backdrop needed on mobile */\n .home-dashboard.sidebar-open::after {\n display: none;\n }\n\n .pin-grid {\n grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n gap: 12px;\n }\n\n .slide-panel {\n width: 100%;\n }\n\n .apps-grid {\n grid-template-columns: 1fr;\n gap: 16px;\n }\n\n .app-card {\n padding: 16px;\n }\n\n .app-icon {\n width: 44px;\n height: 44px;\n }\n\n .app-icon i {\n font-size: var(--mj-text-lg);\n }\n\n .app-name {\n font-size: var(--mj-text-sm);\n }\n\n .nav-preview {\n display: none;\n }\n\n /* Move FAB to bottom-right on mobile \u2014 fixed so it stays visible while scrolling */\n .sidebar-fab-toggle {\n position: fixed;\n top: auto;\n bottom: 20px;\n right: 20px;\n width: 48px;\n height: 48px;\n font-size: var(--mj-text-lg);\n }\n}\n\n@media (max-width: 480px) {\n .main-content {\n padding: 16px;\n padding-bottom: 80px;\n }\n\n .greeting-section h1 {\n font-size: var(--mj-text-xl);\n }\n\n .greeting-section .date {\n font-size: var(--mj-text-sm);\n }\n\n .section-title {\n font-size: var(--mj-text-base);\n margin-bottom: 16px;\n }\n\n .sidebar-fab-toggle {\n bottom: 16px;\n right: 16px;\n width: 44px;\n height: 44px;\n font-size: var(--mj-text-base);\n }\n}\n"] }]
2357
2357
  }], () => [{ type: i1.ApplicationManager }, { type: i2.RecentAccessService }, { type: i0.ChangeDetectorRef }], { appConfigDialog: [{
2358
2358
  type: ViewChild,
2359
2359
  args: ['appConfigDialog']
@@ -4,6 +4,7 @@
4
4
  * Public API exports for the MCP management module.
5
5
  */
6
6
  export { MCPModule } from './mcp.module';
7
+ export { MCPResourceComponent } from './mcp-resource.component';
7
8
  export { MCPDashboardComponent, MCPServerData, MCPConnectionData, MCPToolData, MCPExecutionLogData, MCPDashboardFilters, MCPDashboardStats, MCPDashboardTab } from './mcp-dashboard.component';
8
9
  export { MCPServerDialogComponent, ServerDialogResult, TRANSPORT_TYPES, AUTH_TYPES } from './components/mcp-server-dialog.component';
9
10
  export { MCPConnectionDialogComponent, ConnectionDialogResult } from './components/mcp-connection-dialog.component';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MCP/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EACH,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACb,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACH,4BAA4B,EAC5B,sBAAsB,EACzB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EACH,eAAe,EACf,aAAa,EACb,eAAe,EACf,YAAY,EACf,MAAM,8BAA8B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MCP/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,OAAO,EACH,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EAClB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACH,wBAAwB,EACxB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACb,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACH,4BAA4B,EAC5B,sBAAsB,EACzB,MAAM,8CAA8C,CAAC;AAGtD,OAAO,EACH,eAAe,EACf,aAAa,EACb,eAAe,EACf,YAAY,EACf,MAAM,8BAA8B,CAAC"}
package/dist/MCP/index.js CHANGED
@@ -5,6 +5,8 @@
5
5
  */
6
6
  // Module
7
7
  export { MCPModule } from './mcp.module';
8
+ // Resource Component (wrapper for MCPDashboardComponent)
9
+ export { MCPResourceComponent } from './mcp-resource.component';
8
10
  // Dashboard Component
9
11
  export { MCPDashboardComponent } from './mcp-dashboard.component';
10
12
  // Dialog Components
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/MCP/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,sBAAsB;AACtB,OAAO,EACH,qBAAqB,EAQxB,MAAM,2BAA2B,CAAC;AAEnC,oBAAoB;AACpB,OAAO,EACH,wBAAwB,EAExB,eAAe,EACf,UAAU,EACb,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACH,4BAA4B,EAE/B,MAAM,8CAA8C,CAAC;AAEtD,WAAW;AACX,OAAO,EACH,eAAe,EAIlB,MAAM,8BAA8B,CAAC","sourcesContent":["/**\n * @fileoverview MCP Module Exports\n *\n * Public API exports for the MCP management module.\n */\n\n// Module\nexport { MCPModule } from './mcp.module';\n\n// Dashboard Component\nexport {\n MCPDashboardComponent,\n MCPServerData,\n MCPConnectionData,\n MCPToolData,\n MCPExecutionLogData,\n MCPDashboardFilters,\n MCPDashboardStats,\n MCPDashboardTab\n} from './mcp-dashboard.component';\n\n// Dialog Components\nexport {\n MCPServerDialogComponent,\n ServerDialogResult,\n TRANSPORT_TYPES,\n AUTH_TYPES\n} from './components/mcp-server-dialog.component';\n\nexport {\n MCPConnectionDialogComponent,\n ConnectionDialogResult\n} from './components/mcp-connection-dialog.component';\n\n// Services\nexport {\n MCPToolsService,\n MCPSyncResult,\n MCPSyncProgress,\n MCPSyncState\n} from './services/mcp-tools.service';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/MCP/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,SAAS;AACT,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,yDAAyD;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,sBAAsB;AACtB,OAAO,EACH,qBAAqB,EAQxB,MAAM,2BAA2B,CAAC;AAEnC,oBAAoB;AACpB,OAAO,EACH,wBAAwB,EAExB,eAAe,EACf,UAAU,EACb,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACH,4BAA4B,EAE/B,MAAM,8CAA8C,CAAC;AAEtD,WAAW;AACX,OAAO,EACH,eAAe,EAIlB,MAAM,8BAA8B,CAAC","sourcesContent":["/**\n * @fileoverview MCP Module Exports\n *\n * Public API exports for the MCP management module.\n */\n\n// Module\nexport { MCPModule } from './mcp.module';\n\n// Resource Component (wrapper for MCPDashboardComponent)\nexport { MCPResourceComponent } from './mcp-resource.component';\n\n// Dashboard Component\nexport {\n MCPDashboardComponent,\n MCPServerData,\n MCPConnectionData,\n MCPToolData,\n MCPExecutionLogData,\n MCPDashboardFilters,\n MCPDashboardStats,\n MCPDashboardTab\n} from './mcp-dashboard.component';\n\n// Dialog Components\nexport {\n MCPServerDialogComponent,\n ServerDialogResult,\n TRANSPORT_TYPES,\n AUTH_TYPES\n} from './components/mcp-server-dialog.component';\n\nexport {\n MCPConnectionDialogComponent,\n ConnectionDialogResult\n} from './components/mcp-connection-dialog.component';\n\n// Services\nexport {\n MCPToolsService,\n MCPSyncResult,\n MCPSyncProgress,\n MCPSyncState\n} from './services/mcp-tools.service';\n"]}
@@ -220,6 +220,7 @@ export declare class MCPDashboardComponent extends BaseDashboard implements OnIn
220
220
  */
221
221
  private persistUserPreferences;
222
222
  GetResourceDisplayName(data: ResourceData): Promise<string>;
223
+ GetResourceIconClass(data: ResourceData): Promise<string>;
223
224
  protected initDashboard(): void;
224
225
  protected loadData(): void;
225
226
  ngAfterViewInit(): void;