@memberjunction/ng-explorer-settings 5.42.0 → 5.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/__tests__/role-management-agent-context.test.d.ts +2 -0
  2. package/dist/__tests__/role-management-agent-context.test.d.ts.map +1 -0
  3. package/dist/__tests__/role-management-agent-context.test.js +107 -0
  4. package/dist/__tests__/role-management-agent-context.test.js.map +1 -0
  5. package/dist/__tests__/user-management-agent-context.test.d.ts +2 -0
  6. package/dist/__tests__/user-management-agent-context.test.d.ts.map +1 -0
  7. package/dist/__tests__/user-management-agent-context.test.js +134 -0
  8. package/dist/__tests__/user-management-agent-context.test.js.map +1 -0
  9. package/dist/lib/application-management/application-dialog/application-dialog.component.js +176 -200
  10. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  11. package/dist/lib/application-management/application-management.component.d.ts +7 -0
  12. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  13. package/dist/lib/application-management/application-management.component.js +49 -39
  14. package/dist/lib/application-management/application-management.component.js.map +1 -1
  15. package/dist/lib/application-settings/application-settings.component.js +58 -70
  16. package/dist/lib/application-settings/application-settings.component.js.map +1 -1
  17. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +10 -0
  18. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  19. package/dist/lib/entity-permissions/entity-permissions.component.js +32 -16
  20. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  21. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +32 -33
  22. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  23. package/dist/lib/module.d.ts +1 -1
  24. package/dist/lib/module.d.ts.map +1 -1
  25. package/dist/lib/module.js +13 -4
  26. package/dist/lib/module.js.map +1 -1
  27. package/dist/lib/notification-preferences/notification-preferences.component.js +30 -35
  28. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  29. package/dist/lib/role-management/role-dialog/role-dialog.component.js +26 -46
  30. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  31. package/dist/lib/role-management/role-management-agent-context.d.ts +96 -0
  32. package/dist/lib/role-management/role-management-agent-context.d.ts.map +1 -0
  33. package/dist/lib/role-management/role-management-agent-context.js +85 -0
  34. package/dist/lib/role-management/role-management-agent-context.js.map +1 -0
  35. package/dist/lib/role-management/role-management.component.d.ts +32 -0
  36. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  37. package/dist/lib/role-management/role-management.component.js +236 -41
  38. package/dist/lib/role-management/role-management.component.js.map +1 -1
  39. package/dist/lib/sql-logging/sql-logging.component.js +151 -184
  40. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  41. package/dist/lib/user-app-config/user-app-config.component.js +80 -93
  42. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  43. package/dist/lib/user-management/user-dialog/user-dialog.component.js +20 -21
  44. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  45. package/dist/lib/user-management/user-management-agent-context.d.ts +107 -0
  46. package/dist/lib/user-management/user-management-agent-context.d.ts.map +1 -0
  47. package/dist/lib/user-management/user-management-agent-context.js +132 -0
  48. package/dist/lib/user-management/user-management-agent-context.js.map +1 -0
  49. package/dist/lib/user-management/user-management.component.d.ts +35 -0
  50. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  51. package/dist/lib/user-management/user-management.component.js +311 -71
  52. package/dist/lib/user-management/user-management.component.js.map +1 -1
  53. package/dist/lib/user-profile-settings/user-profile-settings.component.js +52 -70
  54. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  55. package/package.json +19 -19
@@ -273,23 +273,16 @@ function EntityPermissionsComponent_Conditional_13_Conditional_1_Template(rf, ct
273
273
  } }
274
274
  function EntityPermissionsComponent_Conditional_13_Conditional_2_Template(rf, ctx) { if (rf & 1) {
275
275
  const _r9 = i0.ɵɵgetCurrentView();
276
- i0.ɵɵelementStart(0, "div", 21);
277
- i0.ɵɵelement(1, "i", 62);
278
- i0.ɵɵelementStart(2, "h3", 63);
279
- i0.ɵɵtext(3, "No Permissions Found");
276
+ i0.ɵɵelementStart(0, "mj-empty-state", 62);
277
+ i0.ɵɵlistener("Action", function EntityPermissionsComponent_Conditional_13_Conditional_2_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.onEmptyStateAction()); });
280
278
  i0.ɵɵelementEnd();
281
- i0.ɵɵelementStart(4, "p", 64);
282
- i0.ɵɵtext(5, "Try adjusting your filters or refresh the data.");
283
- i0.ɵɵelementEnd();
284
- i0.ɵɵelementStart(6, "button", 65);
285
- i0.ɵɵlistener("click", function EntityPermissionsComponent_Conditional_13_Conditional_2_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.refreshData()); });
286
- i0.ɵɵelement(7, "i", 18);
287
- i0.ɵɵtext(8, " Refresh ");
288
- i0.ɵɵelementEnd()();
279
+ } if (rf & 2) {
280
+ const ctx_r1 = i0.ɵɵnextContext(2);
281
+ i0.ɵɵproperty("Variant", ctx_r1.IsListNarrowed ? "no-results" : "empty")("ActionText", ctx_r1.IsListNarrowed ? "Reset filters" : "Refresh")("ActionIcon", ctx_r1.IsListNarrowed ? "fa-solid fa-rotate-left" : "fa-solid fa-arrows-rotate");
289
282
  } }
290
283
  function EntityPermissionsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
291
284
  i0.ɵɵconditionalCreate(0, EntityPermissionsComponent_Conditional_13_Conditional_0_Template, 3, 0, "div", 19)(1, EntityPermissionsComponent_Conditional_13_Conditional_1_Template, 3, 0, "div", 20);
292
- i0.ɵɵconditionalCreate(2, EntityPermissionsComponent_Conditional_13_Conditional_2_Template, 9, 0, "div", 21);
285
+ i0.ɵɵconditionalCreate(2, EntityPermissionsComponent_Conditional_13_Conditional_2_Template, 1, 3, "mj-empty-state", 21);
293
286
  } if (rf & 2) {
294
287
  const ctx_r1 = i0.ɵɵnextContext();
295
288
  i0.ɵɵconditional(ctx_r1.viewMode === "list" ? 0 : 1);
@@ -551,6 +544,29 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
551
544
  clearAllAppliedFilters() {
552
545
  this.updateFilter({ accessLevel: 'all', roleId: null });
553
546
  }
547
+ /** True when search and/or panel filters are narrowing the list — gates the
548
+ * no-results empty-state "Reset filters" CTA. */
549
+ get IsListNarrowed() {
550
+ return this.filters$.value.entitySearch !== '' || this.TotalActiveFilterCount > 0;
551
+ }
552
+ /** Reset everything narrowing the list (search + Access level + Role) and
553
+ * refresh immediately. Wired to the no-results empty-state CTA. Unlike
554
+ * clearAllAppliedFilters(), this also clears the search box. */
555
+ resetAllFiltersAndSearch() {
556
+ this.filters$.next({ entitySearch: '', accessLevel: 'all', roleId: null });
557
+ this.applyFilters();
558
+ this.cdr.markForCheck();
559
+ }
560
+ /** Empty-state CTA handler: reset filters when the list is narrowed,
561
+ * otherwise reload the data (the original "Refresh" affordance). */
562
+ onEmptyStateAction() {
563
+ if (this.IsListNarrowed) {
564
+ this.resetAllFiltersAndSearch();
565
+ }
566
+ else {
567
+ this.refreshData();
568
+ }
569
+ }
554
570
  toggleEntityExpansion(entityId) {
555
571
  this.expandedEntityId = this.expandedEntityId === entityId ? null : entityId;
556
572
  }
@@ -620,7 +636,7 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
620
636
  this.viewMode = mode;
621
637
  }
622
638
  static ɵfac = function EntityPermissionsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || EntityPermissionsComponent)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
623
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityPermissionsComponent, selectors: [["mj-entity-permissions"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 15, vars: 15, consts: [["AriaLabel", "Filter entity permissions", "Title", "Entity Permissions", "Subtitle", "Manage entity-level access for each role"], ["meta", ""], ["Label", "entities", 3, "Count", "Total"], ["toolbar", ""], ["Placeholder", "Search entities by name or description...", 3, "ValueChange", "Value"], ["Label", "Filters", "Icon", "fa-solid fa-filter", 3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [3, "KeyChange", "Options", "ActiveKey"], ["actions", ""], [3, "Clicked", "Loading"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], ["role", "alert", "aria-live", "assertive", 1, "error-container"], [3, "result", "visible", "data"], ["text", "Loading entity permissions...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["mjButton", "", "variant", "primary", "aria-label", "Retry loading entity permissions", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], ["role", "list", "aria-label", "Entity permissions list", 1, "entities-list"], ["role", "list", "aria-label", "Entity permissions grid", 1, "entities-grid"], ["role", "status", 1, "empty-state"], ["role", "listitem", 1, "entity-card", 3, "expanded"], ["role", "listitem", 1, "entity-card"], ["tabindex", "0", "role", "button", 1, "entity-header", 3, "click", "keydown.enter", "keydown.space"], [1, "entity-info"], ["aria-hidden", "true", 1, "entity-icon-wrapper"], [1, "fa-solid", "fa-table"], [1, "entity-details"], [1, "entity-name"], [1, "entity-description"], [1, "entity-meta"], [1, "access-badge"], ["aria-hidden", "true"], [1, "entity-actions", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Edit Permissions", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], [1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["role", "region", 1, "entity-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], [1, "btn-label"], ["role", "table", "aria-label", "Role permissions", 1, "permissions-grid"], [1, "no-permissions"], ["role", "rowgroup", 1, "permissions-header"], ["role", "row"], ["scope", "col", "role", "columnheader", 1, "role-header"], ["scope", "col", "role", "columnheader", 1, "permission-header"], ["role", "rowgroup"], ["role", "row", 1, "permission-row"], ["role", "cell", 1, "role-name"], ["role", "cell", 1, "permission-cell"], [1, "entity-grid-card", 3, "class"], [1, "entity-grid-card"], [1, "grid-card-header"], ["aria-hidden", "true", 1, "fa-solid", "fa-table"], [1, "grid-card-title"], [1, "grid-card-description"], [1, "grid-card-footer"], [1, "access-label"], [1, "permission-count"], ["aria-hidden", "true", 1, "fa-solid", "fa-shield-alt", "empty-state-icon"], [1, "empty-text"], [1, "empty-subtext"], ["mjButton", "", "variant", "primary", "aria-label", "Refresh permissions data", 3, "click"]], template: function EntityPermissionsComponent_Template(rf, ctx) { if (rf & 1) {
639
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EntityPermissionsComponent, selectors: [["mj-entity-permissions"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 15, vars: 15, consts: [["AriaLabel", "Filter entity permissions", "Title", "Entity Permissions", "Subtitle", "Manage entity-level access for each role"], ["meta", ""], ["Label", "entities", 3, "Count", "Total"], ["toolbar", ""], ["Placeholder", "Search entities by name or description...", 3, "ValueChange", "Value"], ["Label", "Filters", "Icon", "fa-solid fa-filter", 3, "ClearAllRequested", "ActiveCount", "ShowClearAll"], [3, "ValuesChange", "Reset", "Fields", "Values"], [3, "KeyChange", "Options", "ActiveKey"], ["actions", ""], [3, "Clicked", "Loading"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], ["role", "alert", "aria-live", "assertive", 1, "error-container"], [3, "result", "visible", "data"], ["text", "Loading entity permissions...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["mjButton", "", "variant", "primary", "aria-label", "Retry loading entity permissions", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], ["role", "list", "aria-label", "Entity permissions list", 1, "entities-list"], ["role", "list", "aria-label", "Entity permissions grid", 1, "entities-grid"], ["Icon", "fa-solid fa-shield-halved", "Title", "No Permissions Found", "Message", "Try adjusting your filters or refresh the data.", 3, "Variant", "ActionText", "ActionIcon"], ["role", "listitem", 1, "entity-card", 3, "expanded"], ["role", "listitem", 1, "entity-card"], ["tabindex", "0", "role", "button", 1, "entity-header", 3, "click", "keydown.enter", "keydown.space"], [1, "entity-info"], ["aria-hidden", "true", 1, "entity-icon-wrapper"], [1, "fa-solid", "fa-table"], [1, "entity-details"], [1, "entity-name"], [1, "entity-description"], [1, "entity-meta"], [1, "access-badge"], ["aria-hidden", "true"], [1, "entity-actions", 3, "click"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Edit Permissions", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], [1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], ["role", "region", 1, "entity-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], [1, "btn-label"], ["role", "table", "aria-label", "Role permissions", 1, "permissions-grid"], [1, "no-permissions"], ["role", "rowgroup", 1, "permissions-header"], ["role", "row"], ["scope", "col", "role", "columnheader", 1, "role-header"], ["scope", "col", "role", "columnheader", 1, "permission-header"], ["role", "rowgroup"], ["role", "row", 1, "permission-row"], ["role", "cell", 1, "role-name"], ["role", "cell", 1, "permission-cell"], [1, "entity-grid-card", 3, "class"], [1, "entity-grid-card"], [1, "grid-card-header"], ["aria-hidden", "true", 1, "fa-solid", "fa-table"], [1, "grid-card-title"], [1, "grid-card-description"], [1, "grid-card-footer"], [1, "access-label"], [1, "permission-count"], ["Icon", "fa-solid fa-shield-halved", "Title", "No Permissions Found", "Message", "Try adjusting your filters or refresh the data.", 3, "Action", "Variant", "ActionText", "ActionIcon"]], template: function EntityPermissionsComponent_Template(rf, ctx) { if (rf & 1) {
624
640
  i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1);
625
641
  i0.ɵɵelement(2, "mj-stat-badge", 2);
626
642
  i0.ɵɵelementEnd();
@@ -667,7 +683,7 @@ let EntityPermissionsComponent = class EntityPermissionsComponent extends BaseDa
667
683
  i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 13 : -1);
668
684
  i0.ɵɵadvance();
669
685
  i0.ɵɵproperty("visible", ctx.showPermissionDialog)("data", ctx.permissionDialogData);
670
- } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJPageSearchComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent, i2.MJRefreshButtonComponent, i2.MJStatBadgeComponent, i2.MJViewToggleComponent, i3.PermissionDialogComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n\n\n\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n\n\n\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\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 padding: 4rem 2rem;\n}\n\n\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.filter-button[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n\n\n.filter-modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.filter-modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n margin: 0;\n}\n\n\n\n.filter-options-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-option[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%], \n.filter-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] .filter-option-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.mj-search-input[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}", "\n\n\n\n\n\n\n\n\n\n\n\n\n.status-chips[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-shrink: 0;\n}\n\n\n\n\n\n@media (min-width: 640px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n width: 100%;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n min-width: 0;\n box-shadow: none;\n}\n\n\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.875rem;\n }\n}\n\n\n\n.stat-icon-public[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n.stat-icon-restricted[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.stat-icon-permissions[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-700);\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n min-height: 200px;\n padding: 3rem 1.5rem;\n flex-direction: row;\n}\n\n\n\n\n\n.entities-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n\n\n.entity-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n.entity-header[_ngcontent-%COMP%] {\n padding: 1rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--mj-bg-surface);\n transition: background-color 0.2s ease;\n gap: 0.75rem;\n}\n\n.entity-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .entity-header[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n }\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-color-accent-300);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-brand-primary);\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n\n\n.entity-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n.entity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta[_ngcontent-%COMP%] {\n gap: 0.75rem;\n }\n}\n\n\n\n\n\n.access-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n.access-badge.access-public[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.access-badge.access-restricted[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.access-badge.access-custom[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n\n\n.entity-actions[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta[_ngcontent-%COMP%] > .access-badge[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.entity-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n animation: _ngcontent-%COMP%_slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 768px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.75rem;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .mobile-actions-bar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.permissions-grid[_ngcontent-%COMP%] {\n width: 100%;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n border: 1px solid var(--mj-border-default);\n border-collapse: collapse;\n}\n\n\n\n.permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-sunken);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n@media (min-width: 768px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n\n\n.permission-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background-color 0.2s ease;\n}\n\n.permission-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface);\n}\n\n.permission-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header[_ngcontent-%COMP%], \n.permission-header[_ngcontent-%COMP%] {\n text-align: left;\n}\n\n.permission-header[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.role-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell[_ngcontent-%COMP%] {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: var(--mj-color-neutral-400);\n opacity: 0.6;\n}\n\n.no-permissions[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n text-align: center;\n}\n\n\n\n\n\n.entities-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n\n\n.entity-grid-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-grid-card.access-public[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.entity-grid-card.access-restricted[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.entity-grid-card.access-custom[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n.grid-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n }\n}\n\n\n\n.grid-card-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n.grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n\n\n.grid-card-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n\n\n.access-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n@media (min-width: 768px) {\n .empty-state[_ngcontent-%COMP%] {\n padding: 5rem 2.5rem;\n }\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-state-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 0.5rem;\n}\n\n\n\n.error-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container[_ngcontent-%COMP%] {\n padding: 5rem 2.5rem;\n }\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}"] });
686
+ } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderInteriorComponent, i2.MJPageBodyInteriorComponent, i2.MJPageSearchComponent, i2.MJFilterPopoverComponent, i2.MJFilterPanelComponent, i2.MJRefreshButtonComponent, i2.MJStatBadgeComponent, i2.MJViewToggleComponent, i2.MJEmptyStateComponent, i3.PermissionDialogComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem 2.5rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n\n\n\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n\n\n\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\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 padding: 4rem 2rem;\n}\n\n\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.filter-button[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n\n\n.filter-modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal[_ngcontent-%COMP%] {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.filter-modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n\n.filter-modal-footer[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n margin: 0;\n}\n\n\n\n.filter-options-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-option[_ngcontent-%COMP%] input[type=\"checkbox\"][_ngcontent-%COMP%], \n.filter-option[_ngcontent-%COMP%] input[type=\"radio\"][_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.filter-option.selected[_ngcontent-%COMP%] .filter-option-label[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--mj-color-warning-500);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.mj-search-input[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}", "\n\n\n\n\n\n\n\n\n\n\n\n\n.status-chips[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-shrink: 0;\n}\n\n\n\n\n\n@media (min-width: 640px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n width: 100%;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n min-width: 0;\n box-shadow: none;\n}\n\n\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.875rem;\n }\n}\n\n\n\n.stat-icon-public[_ngcontent-%COMP%] {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n.stat-icon-restricted[_ngcontent-%COMP%] {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.stat-icon-permissions[_ngcontent-%COMP%] {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-700);\n}\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n min-height: 200px;\n padding: 3rem 1.5rem;\n flex-direction: row;\n}\n\n\n\n\n\n.entities-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n\n\n.entity-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] {\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n.entity-header[_ngcontent-%COMP%] {\n padding: 1rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--mj-bg-surface);\n transition: background-color 0.2s ease;\n gap: 0.75rem;\n}\n\n.entity-header[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .entity-header[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n }\n}\n\n\n\n.entity-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-color-accent-300);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-brand-primary);\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper[_ngcontent-%COMP%] {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n\n\n.entity-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-name[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n.entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details[_ngcontent-%COMP%] .entity-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}\n\n\n\n.entity-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta[_ngcontent-%COMP%] {\n gap: 0.75rem;\n }\n}\n\n\n\n\n\n.access-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n.access-badge.access-public[_ngcontent-%COMP%] {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.access-badge.access-restricted[_ngcontent-%COMP%] {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.access-badge.access-custom[_ngcontent-%COMP%] {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n\n\n.entity-actions[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta[_ngcontent-%COMP%] > .access-badge[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n\n\n\n\n.entity-content[_ngcontent-%COMP%] {\n padding: 1.25rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n animation: _ngcontent-%COMP%_slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 768px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content[_ngcontent-%COMP%] {\n padding: 1.75rem;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .mobile-actions-bar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.permissions-grid[_ngcontent-%COMP%] {\n width: 100%;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n border: 1px solid var(--mj-border-default);\n border-collapse: collapse;\n}\n\n\n\n.permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-sunken);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n@media (min-width: 768px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n\n\n.permission-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background-color 0.2s ease;\n}\n\n.permission-row[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface);\n}\n\n.permission-row[_ngcontent-%COMP%]:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row[_ngcontent-%COMP%] {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header[_ngcontent-%COMP%], \n.permission-header[_ngcontent-%COMP%] {\n text-align: left;\n}\n\n.permission-header[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.role-name[_ngcontent-%COMP%] {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell[_ngcontent-%COMP%] {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--mj-status-success);\n}\n\n.text-muted[_ngcontent-%COMP%] {\n color: var(--mj-color-neutral-400);\n opacity: 0.6;\n}\n\n.no-permissions[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n text-align: center;\n}\n\n\n\n\n\n.entities-grid[_ngcontent-%COMP%] {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid[_ngcontent-%COMP%] {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n\n\n.entity-grid-card[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-grid-card.access-public[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.entity-grid-card.access-restricted[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.entity-grid-card.access-custom[_ngcontent-%COMP%] {\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n.grid-card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n }\n}\n\n\n\n.grid-card-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n}\n\n\n\n.grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n\n\n.grid-card-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n\n\n.access-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n\n\n.error-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container[_ngcontent-%COMP%] {\n padding: 5rem 2.5rem;\n }\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n margin-bottom: 0.5rem;\n}\n\n\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}"] });
671
687
  };
672
688
  EntityPermissionsComponent = __decorate([
673
689
  RegisterClass(BaseDashboard, 'EntityPermissions')
@@ -675,7 +691,7 @@ EntityPermissionsComponent = __decorate([
675
691
  export { EntityPermissionsComponent };
676
692
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EntityPermissionsComponent, [{
677
693
  type: Component,
678
- args: [{ standalone: false, selector: 'mj-entity-permissions', template: "<!--\n Interior chrome \u2014 see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter entity permissions\"\n Title=\"Entity Permissions\"\n Subtitle=\"Manage entity-level access for each role\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions \u00A72.\n Partition badges (public/restricted/custom) stay dropped \u2014 they mirror\n the Access Level filter chips in [toolbar]. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredEntityAccess.length\"\n [Total]=\"entityAccess.length\"\n Label=\"entities\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search \u00B7 Filter \u00B7 view. Access level + Role\n live behind the one Filter button; applied filters show as removable\n chips below the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search entities by name or description...\"\n [Value]=\"filters$.value.entitySearch\"\n (ValueChange)=\"updateFilter({ entitySearch: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"viewToggleOptions\"\n [ActiveKey]=\"viewMode\"\n (KeyChange)=\"setViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section \u2014 owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading entity permissions...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button\n mjButton variant=\"primary\"\n (click)=\"loadInitialData()\"\n aria-label=\"Retry loading entity permissions\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n @if (!isLoading && !error) {\n @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\" role=\"list\" aria-label=\"Entity permissions list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div\n class=\"entity-card\"\n [class.expanded]=\"isEntityExpanded(ea.entity.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isEntityExpanded(ea.entity.ID)\"\n >\n <div\n class=\"entity-header\"\n (click)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.enter)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.space)=\"toggleEntityExpansion(ea.entity.ID); $event.preventDefault()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Expand permissions for ' + ea.entity.Name\"\n >\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"entity-meta\">\n <span\n class=\"access-badge\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"entity-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"expand-btn\"\n [attr.aria-label]=\"(isEntityExpanded(ea.entity.ID) ? 'Collapse' : 'Expand') + ' permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\" role=\"region\" [attr.aria-label]=\"'Permissions for ' + ea.entity.Name\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n </div>\n </div>\n\n @if (ea.permissions.length > 0) {\n <table class=\"permissions-grid\" role=\"table\" aria-label=\"Role permissions\">\n <thead class=\"permissions-header\" role=\"rowgroup\">\n <tr role=\"row\">\n <th class=\"role-header\" scope=\"col\" role=\"columnheader\">Role</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Create</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Read</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Update</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Delete</th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <tr class=\"permission-row\" role=\"row\">\n <td class=\"role-name\" role=\"cell\">{{ getRoleName(roleId) }}</td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Create: ' + (hasPermission(ea, roleId, 'canCreate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canCreate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Read: ' + (hasPermission(ea, roleId, 'canRead') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canRead') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Update: ' + (hasPermission(ea, roleId, 'canUpdate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canUpdate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Delete: ' + (hasPermission(ea, roleId, 'canDelete') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canDelete') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\" role=\"list\" aria-label=\"Entity permissions grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <article\n class=\"entity-grid-card\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Entity: ' + ea.entity.Name\"\n >\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\" aria-hidden=\"true\"></i>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span\n class=\"access-label\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span\n class=\"permission-count\"\n [attr.aria-label]=\"ea.permissions.length + ' permission' + (ea.permissions.length === 1 ? '' : 's')\"\n >\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </article>\n }\n </div>\n }\n\n @if (filteredEntityAccess.length === 0) {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-shield-alt empty-state-icon\" aria-hidden=\"true\"></i>\n <h3 class=\"empty-text\">No Permissions Found</h3>\n <p class=\"empty-subtext\">Try adjusting your filters or refresh the data.</p>\n <button\n mjButton variant=\"primary\"\n (click)=\"refreshData()\"\n aria-label=\"Refresh permissions data\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Refresh\n </button>\n </div>\n }\n }\n </mj-page-body-interior>\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n\n", styles: ["/* =============================================================================\n Shared Admin Patterns - MJ Design System\n Common styles shared across all admin settings components.\n Component-specific CSS files override these values where needed.\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Host & Container\n ----------------------------------------------------------------------------- */\n:host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content {\n padding: 2rem 2.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (In Sticky Header)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards Grid - Static Display (Non-interactive)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n/* Static Card - No hover effects */\n.mj-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card {\n padding: 1rem 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Stat Icon Containers\n ----------------------------------------------------------------------------- */\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n.stat-icon-total {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Stat Content Typography\n ----------------------------------------------------------------------------- */\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Filters Section\n ----------------------------------------------------------------------------- */\n.filters-section {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Search Input\n ----------------------------------------------------------------------------- */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-icon {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search .mj-search-input {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Expand Button\n ----------------------------------------------------------------------------- */\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Status Badge\n ----------------------------------------------------------------------------- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge i {\n font-size: 0.625rem;\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n.mobile-actions-bar {\n display: none;\n}\n\n.mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header .modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header {\n padding: 1rem;\n }\n\n .modal-header .modal-title {\n font-size: 1.125rem;\n }\n\n .modal-body {\n padding: 1rem;\n }\n\n .modal-footer {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n/* The legacy \"MJ Button System\" rule block (.mj-btn / .mj-btn-primary /\n .mj-btn-secondary / .mj-btn-ghost / .mj-btn-danger / .mj-btn-sm /\n .mj-btn-icon-only / .mj-btn-icon-mobile) was removed 2026-05-19. These\n rules pre-dated the mjButton directive standardization (the directive\n uses BEM modifiers like .mj-btn--primary, single-dash names like\n .mj-btn-primary don't match it anyway). The base .mj-btn rule WAS active\n though \u2014 its component-scoped specificity outranked button.scss's global\n directive styles, so admin sub-page buttons rendered pill-shaped + 44px\n regardless of the variant/size requested via mjButton inputs. Removing the\n rule lets every sub-page fall back to the directive's intended look. */\n\n/* -----------------------------------------------------------------------------\n Filter Button (Mobile Only)\n ----------------------------------------------------------------------------- */\n.filter-button {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button i {\n font-size: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Modal (Mobile Bottom Sheet)\n ----------------------------------------------------------------------------- */\n.filter-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.filter-modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title i {\n color: var(--mj-brand-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.filter-modal-body {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n\n.filter-modal-footer button {\n flex: 1;\n margin: 0;\n}\n\n/* Filter Options Container (Inside Modal) */\n.filter-options-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-option input[type=\"checkbox\"],\n.filter-option input[type=\"radio\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.filter-option.selected .filter-option-label {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--mj-status-error);\n}\n\n.text-warning {\n color: var(--mj-color-warning-500);\n}\n\n.text-success {\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n", "/* =============================================================================\n Entity Permissions Component - Component-Specific Styles\n Shared patterns are in ../shared/styles/_admin-patterns.css\n ============================================================================= */\n\n/* :host already provides flex column / 100% height / overflow hidden via\n _admin-patterns.css. No bespoke container wrapper \u2014 see Section 10 of\n explorer-chrome-conventions. */\n\n/* Status chip group inside <mj-page-header-interior>'s [toolbar] slot. */\n.status-chips {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-shrink: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content Override - Different breakpoints\n ----------------------------------------------------------------------------- */\n@media (min-width: 640px) {\n .scrollable-content {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-grid-4 {\n display: none !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Stats Grid Override - Different layout (margin-based, hidden on mobile)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n margin-bottom: 1rem;\n width: 100%;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .mj-grid-4 {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\n\n/* Stat Card Override - min-width and no box-shadow */\n.mj-card {\n min-width: 0;\n box-shadow: none;\n}\n\n/* Stat Value Override at 768px - different size */\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 1.875rem;\n }\n}\n\n/* Stat Icon Override - Component-specific colors */\n.stat-icon-public {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n.stat-icon-restricted {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.stat-icon-permissions {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-700);\n}\n\n/* Loading Container Override - different layout */\n.loading-container {\n min-height: 200px;\n padding: 3rem 1.5rem;\n flex-direction: row;\n}\n\n/* -----------------------------------------------------------------------------\n Entities List\n ----------------------------------------------------------------------------- */\n.entities-list {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list {\n gap: 1rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Entity Card - Interactive\n ----------------------------------------------------------------------------- */\n.entity-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-card:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded {\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n/* Entity Header */\n.entity-header {\n padding: 1rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--mj-bg-surface);\n transition: background-color 0.2s ease;\n gap: 0.75rem;\n}\n\n.entity-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .entity-header {\n padding: 1.25rem 1.5rem;\n }\n}\n\n/* Entity Info */\n.entity-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info {\n gap: 1rem;\n }\n}\n\n/* Entity Icon Container */\n.entity-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-color-accent-300);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-brand-primary);\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n/* Entity Details */\n.entity-details {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details .entity-name {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details .entity-name {\n font-size: 1.125rem;\n }\n}\n\n.entity-details .entity-description {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details .entity-description {\n font-size: 0.875rem;\n }\n}\n\n/* Entity Meta */\n.entity-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta {\n gap: 0.75rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Access Badges\n ----------------------------------------------------------------------------- */\n.access-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n.access-badge.access-public {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.access-badge.access-restricted {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.access-badge.access-custom {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n/* Entity Actions - Hide on mobile */\n.entity-actions {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta > .access-badge {\n display: none;\n }\n}\n\n/* Expand Button Override - inline-flex, different transition */\n.expand-btn {\n display: inline-flex;\n}\n\n.expand-btn i {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Entity Content - Expanded Area\n ----------------------------------------------------------------------------- */\n.entity-content {\n padding: 1.25rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n animation: slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 768px) {\n .entity-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content {\n padding: 1.75rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .mobile-actions-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons .btn-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Permissions Grid (Table)\n ----------------------------------------------------------------------------- */\n.permissions-grid {\n width: 100%;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n border: 1px solid var(--mj-border-default);\n border-collapse: collapse;\n}\n\n/* Permissions Header */\n.permissions-header tr {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-sunken);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n@media (min-width: 768px) {\n .permissions-header tr {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header tr {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n/* Permission Row */\n.permission-row {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background-color 0.2s ease;\n}\n\n.permission-row:hover {\n background: var(--mj-bg-surface);\n}\n\n.permission-row:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header,\n.permission-header {\n text-align: left;\n}\n\n.permission-header {\n text-align: center;\n}\n\n.role-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Success text */\n.text-success {\n color: var(--mj-status-success);\n}\n\n.text-muted {\n color: var(--mj-color-neutral-400);\n opacity: 0.6;\n}\n\n.no-permissions {\n color: var(--mj-text-secondary);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n text-align: center;\n}\n\n/* -----------------------------------------------------------------------------\n Entities Grid (Grid View)\n ----------------------------------------------------------------------------- */\n.entities-grid {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n/* Entity Grid Card */\n.entity-grid-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-grid-card.access-public {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.entity-grid-card.access-restricted {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.entity-grid-card.access-custom {\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card {\n padding: 1.5rem;\n }\n}\n\n/* Grid Card Header */\n.grid-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header {\n margin-bottom: 1rem;\n }\n}\n\n/* Grid Card Title */\n.grid-card-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title {\n font-size: 1.125rem;\n }\n}\n\n/* Grid Card Description */\n.grid-card-description {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n/* Grid Card Footer */\n.grid-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n/* Access Label */\n.access-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count {\n color: var(--mj-text-secondary);\n}\n\n/* -----------------------------------------------------------------------------\n Empty State Override - flex layout with gap\n ----------------------------------------------------------------------------- */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n@media (min-width: 768px) {\n .empty-state {\n padding: 5rem 2.5rem;\n }\n}\n\n.empty-state .empty-state-icon {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 0.5rem;\n}\n\n/* Error Container Override - flex layout with min-height */\n.error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container {\n padding: 5rem 2.5rem;\n }\n}\n\n.error-container .error-icon {\n margin-bottom: 0.5rem;\n}\n\n/* slideDown Override - uses max-height instead of translateY */\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n\n"] }]
694
+ args: [{ standalone: false, selector: 'mj-entity-permissions', template: "<!--\n Interior chrome \u2014 see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter entity permissions\"\n Title=\"Entity Permissions\"\n Subtitle=\"Manage entity-level access for each role\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions \u00A72.\n Partition badges (public/restricted/custom) stay dropped \u2014 they mirror\n the Access Level filter chips in [toolbar]. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredEntityAccess.length\"\n [Total]=\"entityAccess.length\"\n Label=\"entities\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search \u00B7 Filter \u00B7 view. Access level + Role\n live behind the one Filter button; applied filters show as removable\n chips below the card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search entities by name or description...\"\n [Value]=\"filters$.value.entitySearch\"\n (ValueChange)=\"updateFilter({ entitySearch: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n <mj-view-toggle\n [Options]=\"viewToggleOptions\"\n [ActiveKey]=\"viewMode\"\n (KeyChange)=\"setViewMode($any($event))\">\n </mj-view-toggle>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section \u2014 owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading entity permissions...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button\n mjButton variant=\"primary\"\n (click)=\"loadInitialData()\"\n aria-label=\"Retry loading entity permissions\"\n >\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n @if (!isLoading && !error) {\n @if (viewMode === 'list') {\n <!-- List View -->\n <div class=\"entities-list\" role=\"list\" aria-label=\"Entity permissions list\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <div\n class=\"entity-card\"\n [class.expanded]=\"isEntityExpanded(ea.entity.ID)\"\n role=\"listitem\"\n [attr.aria-expanded]=\"isEntityExpanded(ea.entity.ID)\"\n >\n <div\n class=\"entity-header\"\n (click)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.enter)=\"toggleEntityExpansion(ea.entity.ID)\"\n (keydown.space)=\"toggleEntityExpansion(ea.entity.ID); $event.preventDefault()\"\n tabindex=\"0\"\n role=\"button\"\n [attr.aria-label]=\"'Expand permissions for ' + ea.entity.Name\"\n >\n <div class=\"entity-info\">\n <div class=\"entity-icon-wrapper\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-table\"></i>\n </div>\n <div class=\"entity-details\">\n <h3 class=\"entity-name\">{{ ea.entity.Name }}</h3>\n <p class=\"entity-description\">{{ ea.entity.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"entity-meta\">\n <span\n class=\"access-badge\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"entity-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button\n class=\"expand-btn\"\n [attr.aria-label]=\"(isEntityExpanded(ea.entity.ID) ? 'Collapse' : 'Expand') + ' permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isEntityExpanded(ea.entity.ID)) {\n <div class=\"entity-content\" role=\"region\" [attr.aria-label]=\"'Permissions for ' + ea.entity.Name\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"access-badge\" [class]=\"getAccessLevelClass(ea)\">\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n title=\"Edit Permissions\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n </div>\n </div>\n\n @if (ea.permissions.length > 0) {\n <table class=\"permissions-grid\" role=\"table\" aria-label=\"Role permissions\">\n <thead class=\"permissions-header\" role=\"rowgroup\">\n <tr role=\"row\">\n <th class=\"role-header\" scope=\"col\" role=\"columnheader\">Role</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Create</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Read</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Update</th>\n <th class=\"permission-header\" scope=\"col\" role=\"columnheader\">Delete</th>\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n @for (roleId of ea.rolePermissions.keys(); track roleId) {\n <tr class=\"permission-row\" role=\"row\">\n <td class=\"role-name\" role=\"cell\">{{ getRoleName(roleId) }}</td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Create: ' + (hasPermission(ea, roleId, 'canCreate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canCreate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Read: ' + (hasPermission(ea, roleId, 'canRead') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canRead') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Update: ' + (hasPermission(ea, roleId, 'canUpdate') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canUpdate') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n <td class=\"permission-cell\" role=\"cell\" [attr.aria-label]=\"'Delete: ' + (hasPermission(ea, roleId, 'canDelete') ? 'allowed' : 'denied')\">\n <i\n [class]=\"hasPermission(ea, roleId, 'canDelete') ?\n 'fa-solid fa-check text-success' :\n 'fa-solid fa-times text-muted'\"\n [attr.aria-hidden]=\"true\"\n ></i>\n </td>\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <p class=\"no-permissions\">\n @if (ea.isPublic) {\n This entity is publicly accessible by all users.\n } @else {\n No specific role permissions configured. Access is restricted to system administrators.\n }\n </p>\n }\n </div>\n }\n </div>\n }\n </div>\n } @else {\n <!-- Grid View -->\n <div class=\"entities-grid\" role=\"list\" aria-label=\"Entity permissions grid\">\n @for (ea of filteredEntityAccess; track ea.entity.ID) {\n <article\n class=\"entity-grid-card\"\n [class]=\"getAccessLevelClass(ea)\"\n [attr.aria-label]=\"'Entity: ' + ea.entity.Name\"\n >\n <div class=\"grid-card-header\">\n <i class=\"fa-solid fa-table\" aria-hidden=\"true\"></i>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editEntityPermissions(ea)\"\n [attr.aria-label]=\"'Edit permissions for ' + ea.entity.Name\"\n title=\"Edit Permissions\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <h4 class=\"grid-card-title\">{{ ea.entity.Name }}</h4>\n <p class=\"grid-card-description\">{{ ea.entity.Description || 'No description' }}</p>\n <div class=\"grid-card-footer\">\n <span\n class=\"access-label\"\n [attr.aria-label]=\"'Access level: ' + getAccessLevelLabel(ea)\"\n >\n <i\n [class]=\"getAccessLevelClass(ea) === 'access-public' ? 'fa-solid fa-globe' :\n getAccessLevelClass(ea) === 'access-restricted' ? 'fa-solid fa-lock' :\n 'fa-solid fa-key'\"\n aria-hidden=\"true\"\n ></i>\n {{ getAccessLevelLabel(ea) }}\n </span>\n @if (ea.permissions.length > 0) {\n <span\n class=\"permission-count\"\n [attr.aria-label]=\"ea.permissions.length + ' permission' + (ea.permissions.length === 1 ? '' : 's')\"\n >\n {{ ea.permissions.length }} permission{{ ea.permissions.length === 1 ? '' : 's' }}\n </span>\n }\n </div>\n </article>\n }\n </div>\n }\n\n @if (filteredEntityAccess.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-shield-halved\"\n Title=\"No Permissions Found\"\n Message=\"Try adjusting your filters or refresh the data.\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : 'Refresh'\"\n [ActionIcon]=\"IsListNarrowed ? 'fa-solid fa-rotate-left' : 'fa-solid fa-arrows-rotate'\"\n (Action)=\"onEmptyStateAction()\" />\n }\n }\n </mj-page-body-interior>\n\n <!-- Permission Edit Dialog -->\n <mj-permission-dialog\n [visible]=\"showPermissionDialog\"\n [data]=\"permissionDialogData\"\n (result)=\"onPermissionDialogResult($event)\"\n ></mj-permission-dialog>\n\n", styles: ["/* =============================================================================\n Shared Admin Patterns - MJ Design System\n Common styles shared across all admin settings components.\n Component-specific CSS files override these values where needed.\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n Host & Container\n ----------------------------------------------------------------------------- */\n:host {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--mj-bg-page);\n border-bottom: 1px solid var(--mj-border-default);\n box-shadow: var(--mj-shadow-sm);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n@media (min-width: 1440px) {\n .scrollable-content {\n padding: 2rem 2.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (In Sticky Header)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards Grid - Static Display (Non-interactive)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--mj-bg-page);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n/* Static Card - No hover effects */\n.mj-card {\n background: var(--mj-bg-surface-card);\n border-radius: var(--mj-radius-lg);\n padding: 1rem;\n box-shadow: var(--mj-shadow-sm);\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--mj-border-default);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card {\n padding: 1rem 1.25rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Stat Icon Containers\n ----------------------------------------------------------------------------- */\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n.stat-icon-total {\n background: var(--mj-color-accent-300);\n color: var(--mj-brand-primary);\n}\n\n.stat-icon-active {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Stat Content Typography\n ----------------------------------------------------------------------------- */\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--mj-text-primary);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-secondary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Filters Section\n ----------------------------------------------------------------------------- */\n.filters-section {\n flex-shrink: 0;\n background: var(--mj-bg-surface-card);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--mj-radius-lg);\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.mj-filter-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons {\n display: flex;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-full);\n padding: 4px;\n gap: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Search Input\n ----------------------------------------------------------------------------- */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-search {\n min-width: 400px;\n max-width: 600px;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search {\n min-width: 500px;\n max-width: 800px;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-secondary);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-icon {\n left: 1.25rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-full);\n font-size: 1rem;\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n@media (min-width: 1024px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3.25rem;\n font-size: 1.0625rem;\n }\n}\n\n@media (min-width: 1440px) {\n .mj-search .mj-search-input {\n padding: 1.125rem 1.5rem 1.125rem 3.5rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--mj-text-secondary);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--mj-bg-page);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-xl);\n box-shadow: var(--mj-shadow-sm);\n padding: 1rem;\n border: 1px solid var(--mj-border-default);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Expand Button\n ----------------------------------------------------------------------------- */\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--mj-radius-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Status Badge\n ----------------------------------------------------------------------------- */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active {\n background: var(--mj-color-success-100);\n color: var(--mj-color-success-800);\n border: 1px solid var(--mj-status-success);\n}\n\n.status-badge.status-inactive {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n border: 1px solid var(--mj-status-error);\n}\n\n.status-badge i {\n font-size: 0.625rem;\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n.mobile-actions-bar {\n display: none;\n}\n\n.mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--mj-border-default);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--mj-text-secondary);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--mj-status-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--mj-text-primary);\n margin: 0 0 1.5rem 0;\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-dialog {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl);\n box-shadow: var(--mj-shadow-2xl);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.modal-header .modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--mj-text-primary);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header {\n padding: 1rem;\n }\n\n .modal-header .modal-title {\n font-size: 1.125rem;\n }\n\n .modal-body {\n padding: 1rem;\n }\n\n .modal-footer {\n padding: 1rem;\n flex-direction: column;\n }\n\n}\n\n/* The legacy \"MJ Button System\" rule block (.mj-btn / .mj-btn-primary /\n .mj-btn-secondary / .mj-btn-ghost / .mj-btn-danger / .mj-btn-sm /\n .mj-btn-icon-only / .mj-btn-icon-mobile) was removed 2026-05-19. These\n rules pre-dated the mjButton directive standardization (the directive\n uses BEM modifiers like .mj-btn--primary, single-dash names like\n .mj-btn-primary don't match it anyway). The base .mj-btn rule WAS active\n though \u2014 its component-scoped specificity outranked button.scss's global\n directive styles, so admin sub-page buttons rendered pill-shaped + 44px\n regardless of the variant/size requested via mjButton inputs. Removing the\n rule lets every sub-page fall back to the directive's intended look. */\n\n/* -----------------------------------------------------------------------------\n Filter Button (Mobile Only)\n ----------------------------------------------------------------------------- */\n.filter-button {\n display: none;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.25rem;\n border: 2px solid var(--mj-border-default);\n background: var(--mj-bg-page);\n color: var(--mj-text-primary);\n border-radius: var(--mj-radius-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n min-width: 44px;\n}\n\n.filter-button:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.filter-button:active {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.filter-button i {\n font-size: 1rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Modal (Mobile Bottom Sheet)\n ----------------------------------------------------------------------------- */\n.filter-modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: flex-end;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n padding: 0;\n}\n\n.filter-modal {\n background: var(--mj-bg-page);\n border-radius: var(--mj-radius-2xl) var(--mj-radius-2xl) 0 0;\n box-shadow: var(--mj-shadow-2xl);\n width: 100%;\n max-height: 80vh;\n overflow: hidden;\n animation: slideUpFromBottom 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n}\n\n.filter-modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.25rem 1.5rem;\n border-bottom: 1px solid var(--mj-border-default);\n flex-shrink: 0;\n}\n\n.filter-modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0;\n}\n\n.filter-modal-title i {\n color: var(--mj-brand-primary);\n font-size: 1.375rem;\n}\n\n.filter-modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--mj-text-secondary);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--mj-radius-full);\n transition: all 0.2s ease;\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.filter-modal-close:hover {\n background: var(--mj-brand-primary);\n color: var(--mj-brand-on-primary);\n}\n\n.filter-modal-body {\n padding: 1.5rem;\n overflow-y: auto;\n -webkit-overflow-scrolling: touch;\n flex: 1;\n}\n\n.filter-modal-footer {\n display: flex;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n flex-shrink: 0;\n}\n\n.filter-modal-footer button {\n flex: 1;\n margin: 0;\n}\n\n/* Filter Options Container (Inside Modal) */\n.filter-options-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.filter-group-label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin: 0;\n}\n\n.filter-group-options {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.filter-option {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.875rem 1rem;\n background: var(--mj-bg-surface-sunken);\n border: 2px solid var(--mj-border-default);\n border-radius: var(--mj-radius-lg);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 56px;\n}\n\n.filter-option:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.filter-option.selected {\n background: var(--mj-color-accent-300);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-option input[type=\"checkbox\"],\n.filter-option input[type=\"radio\"] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.filter-option-label {\n flex: 1;\n font-size: 1rem;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n\n.filter-option.selected .filter-option-label {\n color: var(--mj-brand-primary);\n font-weight: 600;\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--mj-status-error);\n}\n\n.text-warning {\n color: var(--mj-color-warning-500);\n}\n\n.text-success {\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(-10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes slideUpFromBottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\nbutton:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n", "/* =============================================================================\n Entity Permissions Component - Component-Specific Styles\n Shared patterns are in ../shared/styles/_admin-patterns.css\n ============================================================================= */\n\n/* :host already provides flex column / 100% height / overflow hidden via\n _admin-patterns.css. No bespoke container wrapper \u2014 see Section 10 of\n explorer-chrome-conventions. */\n\n/* Status chip group inside <mj-page-header-interior>'s [toolbar] slot. */\n.status-chips {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-2);\n flex-shrink: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content Override - Different breakpoints\n ----------------------------------------------------------------------------- */\n@media (min-width: 640px) {\n .scrollable-content {\n padding: 1.25rem;\n }\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (max-width: 639px) {\n .mj-grid-4 {\n display: none !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Stats Grid Override - Different layout (margin-based, hidden on mobile)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n margin-bottom: 1rem;\n width: 100%;\n padding: 0;\n background: transparent;\n}\n\n@media (max-width: 639px) {\n .mj-grid-4 {\n display: none !important;\n }\n}\n\n@media (min-width: 640px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n gap: 1.25rem;\n margin-bottom: 1.25rem;\n }\n}\n\n/* Stat Card Override - min-width and no box-shadow */\n.mj-card {\n min-width: 0;\n box-shadow: none;\n}\n\n/* Stat Value Override at 768px - different size */\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 1.875rem;\n }\n}\n\n/* Stat Icon Override - Component-specific colors */\n.stat-icon-public {\n background: var(--mj-color-success-100);\n color: var(--mj-status-success);\n}\n\n.stat-icon-restricted {\n background: var(--mj-color-error-100);\n color: var(--mj-status-error);\n}\n\n.stat-icon-permissions {\n background: var(--mj-color-warning-50);\n color: var(--mj-color-warning-700);\n}\n\n/* Loading Container Override - different layout */\n.loading-container {\n min-height: 200px;\n padding: 3rem 1.5rem;\n flex-direction: row;\n}\n\n/* -----------------------------------------------------------------------------\n Entities List\n ----------------------------------------------------------------------------- */\n.entities-list {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n overflow: visible;\n}\n\n@media (min-width: 768px) {\n .entities-list {\n gap: 1rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Entity Card - Interactive\n ----------------------------------------------------------------------------- */\n.entity-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-card:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded {\n box-shadow: var(--mj-shadow-lg);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n/* Entity Header */\n.entity-header {\n padding: 1rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n cursor: pointer;\n background: var(--mj-bg-surface);\n transition: background-color 0.2s ease;\n gap: 0.75rem;\n}\n\n.entity-header:hover {\n background: var(--mj-bg-surface-sunken);\n}\n\n@media (min-width: 768px) {\n .entity-header {\n padding: 1.25rem 1.5rem;\n }\n}\n\n/* Entity Info */\n.entity-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n@media (min-width: 768px) {\n .entity-info {\n gap: 1rem;\n }\n}\n\n/* Entity Icon Container */\n.entity-icon-wrapper {\n width: 48px;\n height: 48px;\n border-radius: var(--mj-radius-lg);\n background: var(--mj-color-accent-300);\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--mj-brand-primary);\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-icon-wrapper {\n width: 52px;\n height: 52px;\n font-size: 1.375rem;\n }\n}\n\n/* Entity Details */\n.entity-details {\n flex: 1;\n min-width: 0;\n}\n\n.entity-details .entity-name {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.25rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details .entity-name {\n font-size: 1.125rem;\n }\n}\n\n.entity-details .entity-description {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .entity-details .entity-description {\n font-size: 0.875rem;\n }\n}\n\n/* Entity Meta */\n.entity-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .entity-meta {\n gap: 0.75rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Access Badges\n ----------------------------------------------------------------------------- */\n.access-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--mj-radius-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n white-space: nowrap;\n}\n\n@media (min-width: 768px) {\n .access-badge {\n padding: 0.5rem 1rem;\n font-size: 0.8125rem;\n }\n}\n\n.access-badge.access-public {\n background: var(--mj-status-success-bg);\n color: var(--mj-status-success-text);\n border: 1px solid var(--mj-status-success-border);\n}\n\n.access-badge.access-restricted {\n background: var(--mj-status-error-bg);\n color: var(--mj-status-error-text);\n border: 1px solid var(--mj-status-error-border);\n}\n\n.access-badge.access-custom {\n background: var(--mj-status-warning-bg);\n color: var(--mj-status-warning-text);\n border: 1px solid var(--mj-status-warning-border);\n}\n\n/* Entity Actions - Hide on mobile */\n.entity-actions {\n display: none;\n}\n\n@media (min-width: 640px) {\n .entity-actions {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n@media (max-width: 639px) {\n .entity-meta > .access-badge {\n display: none;\n }\n}\n\n/* Expand Button Override - inline-flex, different transition */\n.expand-btn {\n display: inline-flex;\n}\n\n.expand-btn i {\n transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* -----------------------------------------------------------------------------\n Entity Content - Expanded Area\n ----------------------------------------------------------------------------- */\n.entity-content {\n padding: 1.25rem;\n background: var(--mj-bg-surface);\n border-top: 1px solid var(--mj-border-default);\n animation: slideDown 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n@media (min-width: 768px) {\n .entity-content {\n padding: 1.5rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entity-content {\n padding: 1.75rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Actions Bar\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .mobile-actions-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.75rem;\n margin: -1.25rem -1.25rem 1rem -1.25rem;\n background: var(--mj-bg-surface-sunken);\n border-bottom: 1px solid var(--mj-border-default);\n }\n\n .mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n }\n\n .mobile-action-buttons .btn-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Permissions Grid (Table)\n ----------------------------------------------------------------------------- */\n.permissions-grid {\n width: 100%;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n overflow: hidden;\n border: 1px solid var(--mj-border-default);\n border-collapse: collapse;\n}\n\n/* Permissions Header */\n.permissions-header tr {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface-sunken);\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n@media (min-width: 768px) {\n .permissions-header tr {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permissions-header tr {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n font-size: 0.75rem;\n }\n}\n\n/* Permission Row */\n.permission-row {\n display: grid;\n grid-template-columns: 2fr 1fr 1fr 1fr 1fr;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--mj-border-default);\n transition: background-color 0.2s ease;\n}\n\n.permission-row:hover {\n background: var(--mj-bg-surface);\n}\n\n.permission-row:last-child {\n border-bottom: none;\n}\n\n@media (min-width: 768px) {\n .permission-row {\n padding: 1rem 1.25rem;\n gap: 0.75rem;\n }\n}\n\n@media (max-width: 639px) {\n .permission-row {\n grid-template-columns: 1.5fr 1fr 1fr 1fr 1fr;\n padding: 0.625rem 0.75rem;\n }\n}\n\n.role-header,\n.permission-header {\n text-align: left;\n}\n\n.permission-header {\n text-align: center;\n}\n\n.role-name {\n font-weight: 500;\n color: var(--mj-text-primary);\n font-size: 0.875rem;\n display: flex;\n align-items: center;\n}\n\n@media (max-width: 639px) {\n .role-name {\n font-size: 0.75rem;\n }\n}\n\n.permission-cell {\n text-align: center;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Success text */\n.text-success {\n color: var(--mj-status-success);\n}\n\n.text-muted {\n color: var(--mj-color-neutral-400);\n opacity: 0.6;\n}\n\n.no-permissions {\n color: var(--mj-text-secondary);\n font-size: 0.875rem;\n margin: 0;\n padding: 1rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-lg);\n text-align: center;\n}\n\n/* -----------------------------------------------------------------------------\n Entities Grid (Grid View)\n ----------------------------------------------------------------------------- */\n.entities-grid {\n display: grid;\n gap: 0.75rem;\n grid-template-columns: 1fr;\n}\n\n@media (min-width: 640px) {\n .entities-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n }\n}\n\n@media (min-width: 768px) {\n .entities-grid {\n gap: 1.25rem;\n }\n}\n\n@media (min-width: 1024px) {\n .entities-grid {\n grid-template-columns: repeat(3, 1fr);\n gap: 1.5rem;\n }\n}\n\n/* Entity Grid Card */\n.entity-grid-card {\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-xl);\n padding: 1.25rem;\n position: relative;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.entity-grid-card:hover {\n box-shadow: var(--mj-shadow-md);\n border-color: var(--mj-brand-primary);\n}\n\n.entity-grid-card.access-public {\n border-left: 4px solid var(--mj-status-success);\n}\n\n.entity-grid-card.access-restricted {\n border-left: 4px solid var(--mj-status-error);\n}\n\n.entity-grid-card.access-custom {\n border-left: 4px solid var(--mj-color-warning-500);\n}\n\n@media (min-width: 768px) {\n .entity-grid-card {\n padding: 1.5rem;\n }\n}\n\n/* Grid Card Header */\n.grid-card-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n font-size: 1.5rem;\n color: var(--mj-brand-primary);\n}\n\n@media (min-width: 768px) {\n .grid-card-header {\n margin-bottom: 1rem;\n }\n}\n\n/* Grid Card Title */\n.grid-card-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n@media (min-width: 768px) {\n .grid-card-title {\n font-size: 1.125rem;\n }\n}\n\n/* Grid Card Description */\n.grid-card-description {\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n margin: 0 0 0.75rem 0;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n}\n\n@media (min-width: 768px) {\n .grid-card-description {\n font-size: 0.875rem;\n margin: 0 0 1rem 0;\n }\n}\n\n/* Grid Card Footer */\n.grid-card-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n font-size: 0.8125rem;\n color: var(--mj-text-secondary);\n}\n\n/* Access Label */\n.access-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n font-weight: 500;\n}\n\n.permission-count {\n color: var(--mj-text-secondary);\n}\n\n/* Error Container Override - flex layout with min-height */\n.error-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 200px;\n}\n\n@media (min-width: 768px) {\n .error-container {\n padding: 5rem 2.5rem;\n }\n}\n\n.error-container .error-icon {\n margin-bottom: 0.5rem;\n}\n\n/* slideDown Override - uses max-height instead of translateY */\n@keyframes slideDown {\n from {\n opacity: 0;\n max-height: 0;\n }\n to {\n opacity: 1;\n max-height: 800px;\n }\n}\n\n"] }]
679
695
  }], () => [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }], null); })();
680
696
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EntityPermissionsComponent, { className: "EntityPermissionsComponent", filePath: "src/lib/entity-permissions/entity-permissions.component.ts", lineNumber: 50 }); })();
681
697
  //# sourceMappingURL=entity-permissions.component.js.map