@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
@@ -12,26 +12,15 @@ import * as i4 from "@memberjunction/ng-ui-components";
12
12
  const _forTrack0 = ($index, $item) => $item.name;
13
13
  function UserProfileSettingsComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
14
14
  const _r1 = i0.ɵɵgetCurrentView();
15
- i0.ɵɵelementStart(0, "div", 4);
16
- i0.ɵɵelement(1, "i", 29);
17
- i0.ɵɵelementStart(2, "span");
18
- i0.ɵɵtext(3);
15
+ i0.ɵɵelementStart(0, "mj-alert", 29);
16
+ i0.ɵɵlistener("Dismissed", function UserProfileSettingsComponent_Conditional_6_Template_mj_alert_Dismissed_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.errorMessage = ""); });
19
17
  i0.ɵɵelementEnd();
20
- i0.ɵɵelementStart(4, "button", 30);
21
- i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.errorMessage = ""); });
22
- i0.ɵɵelement(5, "i", 31);
23
- i0.ɵɵelementEnd()();
24
18
  } if (rf & 2) {
25
19
  const ctx_r1 = i0.ɵɵnextContext();
26
- i0.ɵɵadvance(3);
27
- i0.ɵɵtextInterpolate(ctx_r1.errorMessage);
20
+ i0.ɵɵproperty("Message", ctx_r1.errorMessage);
28
21
  } }
29
22
  function UserProfileSettingsComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
30
- i0.ɵɵelementStart(0, "div", 5);
31
- i0.ɵɵelement(1, "i", 32);
32
- i0.ɵɵelementStart(2, "span");
33
- i0.ɵɵtext(3, "Avatar updated successfully!");
34
- i0.ɵɵelementEnd()();
23
+ i0.ɵɵelement(0, "mj-alert", 5);
35
24
  } }
36
25
  function UserProfileSettingsComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
37
26
  i0.ɵɵelement(0, "img", 9);
@@ -41,7 +30,7 @@ function UserProfileSettingsComponent_Conditional_12_Template(rf, ctx) { if (rf
41
30
  } }
42
31
  function UserProfileSettingsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
43
32
  i0.ɵɵelementStart(0, "div", 10);
44
- i0.ɵɵelement(1, "i", 33);
33
+ i0.ɵɵelement(1, "i", 30);
45
34
  i0.ɵɵelementEnd();
46
35
  } if (rf & 2) {
47
36
  const ctx_r1 = i0.ɵɵnextContext();
@@ -50,21 +39,21 @@ function UserProfileSettingsComponent_Conditional_13_Template(rf, ctx) { if (rf
50
39
  } }
51
40
  function UserProfileSettingsComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
52
41
  i0.ɵɵelementStart(0, "div", 11);
53
- i0.ɵɵelement(1, "i", 34);
42
+ i0.ɵɵelement(1, "i", 31);
54
43
  i0.ɵɵelementStart(2, "span");
55
44
  i0.ɵɵtext(3, "No avatar selected");
56
45
  i0.ɵɵelementEnd()();
57
46
  } }
58
47
  function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template(rf, ctx) { if (rf & 1) {
59
48
  const _r5 = i0.ɵɵgetCurrentView();
60
- i0.ɵɵelementStart(0, "div", 39);
61
- i0.ɵɵelement(1, "i", 40);
49
+ i0.ɵɵelementStart(0, "div", 36);
50
+ i0.ɵɵelement(1, "i", 37);
62
51
  i0.ɵɵelementStart(2, "span");
63
52
  i0.ɵɵtext(3);
64
53
  i0.ɵɵelementEnd();
65
- i0.ɵɵelementStart(4, "button", 41);
54
+ i0.ɵɵelementStart(4, "button", 38);
66
55
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearUpload()); });
67
- i0.ɵɵelement(5, "i", 31);
56
+ i0.ɵɵelement(5, "i", 39);
68
57
  i0.ɵɵelementEnd()();
69
58
  } if (rf & 2) {
70
59
  const ctx_r1 = i0.ɵɵnextContext(2);
@@ -73,19 +62,19 @@ function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template(rf,
73
62
  } }
74
63
  function UserProfileSettingsComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
75
64
  const _r3 = i0.ɵɵgetCurrentView();
76
- i0.ɵɵelementStart(0, "div", 22)(1, "input", 35, 0);
65
+ i0.ɵɵelementStart(0, "div", 22)(1, "input", 32, 0);
77
66
  i0.ɵɵlistener("change", function UserProfileSettingsComponent_Conditional_33_Template_input_change_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFileSelected($event)); });
78
67
  i0.ɵɵelementEnd();
79
- i0.ɵɵelementStart(3, "button", 36);
68
+ i0.ɵɵelementStart(3, "button", 33);
80
69
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_33_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const fileInput_r4 = i0.ɵɵreference(2); return i0.ɵɵresetView(fileInput_r4.click()); });
81
70
  i0.ɵɵelement(4, "i", 14);
82
71
  i0.ɵɵtext(5, " Choose Image ");
83
72
  i0.ɵɵelementEnd();
84
- i0.ɵɵelementStart(6, "div", 37);
85
- i0.ɵɵelement(7, "i", 38);
73
+ i0.ɵɵelementStart(6, "div", 34);
74
+ i0.ɵɵelement(7, "i", 35);
86
75
  i0.ɵɵtext(8, " Max 200KB - PNG, JPG, GIF, WEBP ");
87
76
  i0.ɵɵelementEnd();
88
- i0.ɵɵconditionalCreate(9, UserProfileSettingsComponent_Conditional_33_Conditional_9_Template, 6, 1, "div", 39);
77
+ i0.ɵɵconditionalCreate(9, UserProfileSettingsComponent_Conditional_33_Conditional_9_Template, 6, 1, "div", 36);
89
78
  i0.ɵɵelementEnd();
90
79
  } if (rf & 2) {
91
80
  const ctx_r1 = i0.ɵɵnextContext();
@@ -94,15 +83,15 @@ function UserProfileSettingsComponent_Conditional_33_Template(rf, ctx) { if (rf
94
83
  } }
95
84
  function UserProfileSettingsComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
96
85
  const _r6 = i0.ɵɵgetCurrentView();
97
- i0.ɵɵelementStart(0, "div", 23)(1, "label", 42);
86
+ i0.ɵɵelementStart(0, "div", 23)(1, "label", 40);
98
87
  i0.ɵɵtext(2, "Image URL");
99
88
  i0.ɵɵelementEnd();
100
- i0.ɵɵelementStart(3, "input", 43);
89
+ i0.ɵɵelementStart(3, "input", 41);
101
90
  i0.ɵɵtwoWayListener("ngModelChange", function UserProfileSettingsComponent_Conditional_34_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.imageUrlInput, $event) || (ctx_r1.imageUrlInput = $event); return i0.ɵɵresetView($event); });
102
91
  i0.ɵɵlistener("input", function UserProfileSettingsComponent_Conditional_34_Template_input_input_3_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onUrlChange()); });
103
92
  i0.ɵɵelementEnd();
104
- i0.ɵɵelementStart(4, "div", 44);
105
- i0.ɵɵelement(5, "i", 38);
93
+ i0.ɵɵelementStart(4, "div", 42);
94
+ i0.ɵɵelement(5, "i", 35);
106
95
  i0.ɵɵtext(6, " Enter a URL to an image hosted online ");
107
96
  i0.ɵɵelementEnd()();
108
97
  } if (rf & 2) {
@@ -112,16 +101,16 @@ function UserProfileSettingsComponent_Conditional_34_Template(rf, ctx) { if (rf
112
101
  } }
113
102
  function UserProfileSettingsComponent_Conditional_35_Conditional_5_Template(rf, ctx) { if (rf & 1) {
114
103
  const _r8 = i0.ɵɵgetCurrentView();
115
- i0.ɵɵelementStart(0, "button", 53);
104
+ i0.ɵɵelementStart(0, "button", 51);
116
105
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_35_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearIconSearch()); });
117
- i0.ɵɵelement(1, "i", 31);
106
+ i0.ɵɵelement(1, "i", 39);
118
107
  i0.ɵɵelementEnd();
119
108
  } }
120
109
  function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template(rf, ctx) { if (rf & 1) {
121
110
  const _r9 = i0.ɵɵgetCurrentView();
122
- i0.ɵɵelementStart(0, "button", 58);
111
+ i0.ɵɵelementStart(0, "button", 56);
123
112
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template_button_click_0_listener() { const icon_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.selectIcon(icon_r10)); });
124
- i0.ɵɵelement(1, "i", 33);
113
+ i0.ɵɵelement(1, "i", 30);
125
114
  i0.ɵɵelementEnd();
126
115
  } if (rf & 2) {
127
116
  const icon_r10 = ctx.$implicit;
@@ -133,11 +122,11 @@ function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_T
133
122
  i0.ɵɵclassMap(icon_r10);
134
123
  } }
135
124
  function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
136
- i0.ɵɵelementStart(0, "div", 54)(1, "h4", 55);
125
+ i0.ɵɵelementStart(0, "div", 52)(1, "h4", 53);
137
126
  i0.ɵɵtext(2);
138
127
  i0.ɵɵelementEnd();
139
- i0.ɵɵelementStart(3, "div", 56);
140
- i0.ɵɵrepeaterCreate(4, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template, 2, 7, "button", 57, i0.ɵɵrepeaterTrackByIdentity);
128
+ i0.ɵɵelementStart(3, "div", 54);
129
+ i0.ɵɵrepeaterCreate(4, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template, 2, 7, "button", 55, i0.ɵɵrepeaterTrackByIdentity);
141
130
  i0.ɵɵelementEnd()();
142
131
  } if (rf & 2) {
143
132
  const category_r11 = ctx.$implicit;
@@ -149,35 +138,28 @@ function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Templat
149
138
  i0.ɵɵrepeater(category_r11.icons);
150
139
  } }
151
140
  function UserProfileSettingsComponent_Conditional_35_Conditional_9_Template(rf, ctx) { if (rf & 1) {
152
- i0.ɵɵrepeaterCreate(0, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Template, 6, 2, "div", 54, _forTrack0);
141
+ i0.ɵɵrepeaterCreate(0, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Template, 6, 2, "div", 52, _forTrack0);
153
142
  } if (rf & 2) {
154
143
  const ctx_r1 = i0.ɵɵnextContext(2);
155
144
  i0.ɵɵrepeater(ctx_r1.filteredIconCategories);
156
145
  } }
157
146
  function UserProfileSettingsComponent_Conditional_35_Conditional_10_Template(rf, ctx) { if (rf & 1) {
158
- i0.ɵɵelementStart(0, "div", 52);
159
- i0.ɵɵelement(1, "i", 59);
160
- i0.ɵɵelementStart(2, "p", 60);
161
- i0.ɵɵtext(3, "No icons found");
162
- i0.ɵɵelementEnd();
163
- i0.ɵɵelementStart(4, "p", 61);
164
- i0.ɵɵtext(5, "Try a different search term");
165
- i0.ɵɵelementEnd()();
147
+ i0.ɵɵelement(0, "mj-empty-state", 50);
166
148
  } }
167
149
  function UserProfileSettingsComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
168
150
  const _r7 = i0.ɵɵgetCurrentView();
169
- i0.ɵɵelementStart(0, "div", 24)(1, "div", 45)(2, "div", 46);
170
- i0.ɵɵelement(3, "i", 47);
171
- i0.ɵɵelementStart(4, "input", 48);
151
+ i0.ɵɵelementStart(0, "div", 24)(1, "div", 43)(2, "div", 44);
152
+ i0.ɵɵelement(3, "i", 45);
153
+ i0.ɵɵelementStart(4, "input", 46);
172
154
  i0.ɵɵlistener("input", function UserProfileSettingsComponent_Conditional_35_Template_input_input_4_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onIconSearchChange($event)); });
173
155
  i0.ɵɵelementEnd();
174
- i0.ɵɵconditionalCreate(5, UserProfileSettingsComponent_Conditional_35_Conditional_5_Template, 2, 0, "button", 49);
156
+ i0.ɵɵconditionalCreate(5, UserProfileSettingsComponent_Conditional_35_Conditional_5_Template, 2, 0, "button", 47);
175
157
  i0.ɵɵelementEnd();
176
- i0.ɵɵelementStart(6, "div", 50);
158
+ i0.ɵɵelementStart(6, "div", 48);
177
159
  i0.ɵɵtext(7);
178
160
  i0.ɵɵelementEnd()();
179
- i0.ɵɵelementStart(8, "div", 51);
180
- i0.ɵɵconditionalCreate(9, UserProfileSettingsComponent_Conditional_35_Conditional_9_Template, 2, 0)(10, UserProfileSettingsComponent_Conditional_35_Conditional_10_Template, 6, 0, "div", 52);
161
+ i0.ɵɵelementStart(8, "div", 49);
162
+ i0.ɵɵconditionalCreate(9, UserProfileSettingsComponent_Conditional_35_Conditional_9_Template, 2, 0)(10, UserProfileSettingsComponent_Conditional_35_Conditional_10_Template, 1, 0, "mj-empty-state", 50);
181
163
  i0.ɵɵelementEnd()();
182
164
  } if (rf & 2) {
183
165
  const ctx_r1 = i0.ɵɵnextContext();
@@ -212,29 +194,29 @@ function UserProfileSettingsComponent_Conditional_36_Conditional_17_Template(rf,
212
194
  } }
213
195
  function UserProfileSettingsComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
214
196
  const _r12 = i0.ɵɵgetCurrentView();
215
- i0.ɵɵelementStart(0, "div", 25)(1, "div", 62);
216
- i0.ɵɵelement(2, "i", 38);
197
+ i0.ɵɵelementStart(0, "div", 25)(1, "div", 57);
198
+ i0.ɵɵelement(2, "i", 35);
217
199
  i0.ɵɵelementStart(3, "p");
218
200
  i0.ɵɵtext(4, "Sync your avatar from your authentication provider account");
219
201
  i0.ɵɵelementEnd()();
220
- i0.ɵɵelementStart(5, "button", 63);
202
+ i0.ɵɵelementStart(5, "button", 58);
221
203
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.syncFromProvider()); });
222
204
  i0.ɵɵelement(6, "i", 20);
223
205
  i0.ɵɵconditionalCreate(7, UserProfileSettingsComponent_Conditional_36_Conditional_7_Template, 2, 0, "span")(8, UserProfileSettingsComponent_Conditional_36_Conditional_8_Template, 2, 0, "span");
224
206
  i0.ɵɵelementEnd();
225
- i0.ɵɵelementStart(9, "div", 64);
226
- i0.ɵɵelement(10, "i", 65);
207
+ i0.ɵɵelementStart(9, "div", 59);
208
+ i0.ɵɵelement(10, "i", 60);
227
209
  i0.ɵɵelementStart(11, "small");
228
210
  i0.ɵɵtext(12, "This will download your profile photo from Microsoft and save it to your profile");
229
211
  i0.ɵɵelementEnd()();
230
- i0.ɵɵelement(13, "hr", 66);
231
- i0.ɵɵelementStart(14, "button", 67);
212
+ i0.ɵɵelement(13, "hr", 61);
213
+ i0.ɵɵelementStart(14, "button", 62);
232
214
  i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.revertToDefault()); });
233
- i0.ɵɵelement(15, "i", 68);
215
+ i0.ɵɵelement(15, "i", 63);
234
216
  i0.ɵɵconditionalCreate(16, UserProfileSettingsComponent_Conditional_36_Conditional_16_Template, 2, 0, "span")(17, UserProfileSettingsComponent_Conditional_36_Conditional_17_Template, 2, 0, "span");
235
217
  i0.ɵɵelementEnd();
236
- i0.ɵɵelementStart(18, "div", 64);
237
- i0.ɵɵelement(19, "i", 38);
218
+ i0.ɵɵelementStart(18, "div", 59);
219
+ i0.ɵɵelement(19, "i", 35);
238
220
  i0.ɵɵelementStart(20, "small");
239
221
  i0.ɵɵtext(21, "Clears your avatar settings and restores the automatic sync from your auth provider");
240
222
  i0.ɵɵelementEnd()()();
@@ -250,13 +232,13 @@ function UserProfileSettingsComponent_Conditional_36_Template(rf, ctx) { if (rf
250
232
  i0.ɵɵconditional(ctx_r1.isSaving ? 16 : 17);
251
233
  } }
252
234
  function UserProfileSettingsComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
253
- i0.ɵɵelement(0, "i", 69);
235
+ i0.ɵɵelement(0, "i", 64);
254
236
  i0.ɵɵelementStart(1, "span");
255
237
  i0.ɵɵtext(2, "Saving...");
256
238
  i0.ɵɵelementEnd();
257
239
  } }
258
240
  function UserProfileSettingsComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
259
- i0.ɵɵelement(0, "i", 70);
241
+ i0.ɵɵelement(0, "i", 65);
260
242
  i0.ɵɵelementStart(1, "span");
261
243
  i0.ɵɵtext(2, "Save Changes");
262
244
  i0.ɵɵelementEnd();
@@ -753,15 +735,15 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
753
735
  }, 3000);
754
736
  }
755
737
  static ɵfac = function UserProfileSettingsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserProfileSettingsComponent)(i0.ɵɵdirectiveInject(i1.UserAvatarService), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
756
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 43, vars: 22, consts: [["fileInput", ""], [1, "user-profile-settings"], [1, "profile-header"], [1, "description"], ["role", "alert", 1, "alert", "alert-error"], ["role", "status", "aria-live", "polite", 1, "alert", "alert-success"], [1, "avatar-preview-section"], [1, "preview-label"], [1, "preview-container"], ["alt", "Avatar preview", 1, "preview-image", 3, "src"], [1, "preview-icon-wrapper"], [1, "preview-placeholder"], ["role", "tablist", "aria-label", "Avatar customization options", 1, "tab-navigation"], ["role", "tab", "aria-controls", "panel-upload", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-upload"], ["role", "tab", "aria-controls", "panel-url", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["role", "tab", "aria-controls", "panel-icon", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-icons"], ["role", "tab", "aria-controls", "panel-provider", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-brands", "fa-microsoft"], [1, "tab-content"], ["id", "panel-upload", "role", "tabpanel", 1, "upload-section"], ["id", "panel-url", "role", "tabpanel", 1, "url-section"], ["id", "panel-icon", "role", "tabpanel", 1, "icon-section"], ["id", "panel-provider", "role", "tabpanel", 1, "provider-section"], [1, "action-buttons"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], ["aria-label", "Dismiss error", 1, "close-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], ["aria-hidden", "true"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["type", "file", "accept", "image/png,image/jpeg,image/jpg,image/gif,image/webp", 2, "display", "none", 3, "change"], [1, "upload-btn", 3, "click"], [1, "upload-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], [1, "selected-file"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-image"], ["aria-label", "Remove selected file", 1, "remove-btn", 3, "click"], ["for", "imageUrl"], ["type", "text", "id", "imageUrl", "placeholder", "https://example.com/avatar.jpg", 1, "url-input", 3, "ngModelChange", "input", "ngModel"], [1, "url-info"], [1, "icon-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search icons by name...", "aria-label", "Search icons", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Clear search", 1, "mj-search-clear"], [1, "icon-filter-info"], [1, "icon-categories-container"], [1, "empty-state"], ["aria-label", "Clear search", 1, "mj-search-clear", 3, "click"], [1, "icon-category"], [1, "category-title"], ["role", "radiogroup", 1, "icon-grid"], ["role", "radio", 1, "icon-option", 3, "selected", "title"], ["role", "radio", 1, "icon-option", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "provider-info"], [1, "sync-btn", 3, "click", "disabled"], [1, "provider-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-lightbulb"], [1, "provider-divider"], [1, "revert-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function UserProfileSettingsComponent_Template(rf, ctx) { if (rf & 1) {
738
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 43, vars: 22, consts: [["fileInput", ""], [1, "user-profile-settings"], [1, "profile-header"], [1, "description"], ["Variant", "error", "Dismissible", "", 3, "Message"], ["Variant", "success", "Message", "Avatar updated successfully!"], [1, "avatar-preview-section"], [1, "preview-label"], [1, "preview-container"], ["alt", "Avatar preview", 1, "preview-image", 3, "src"], [1, "preview-icon-wrapper"], [1, "preview-placeholder"], ["role", "tablist", "aria-label", "Avatar customization options", 1, "tab-navigation"], ["role", "tab", "aria-controls", "panel-upload", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-upload"], ["role", "tab", "aria-controls", "panel-url", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["role", "tab", "aria-controls", "panel-icon", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-icons"], ["role", "tab", "aria-controls", "panel-provider", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-brands", "fa-microsoft"], [1, "tab-content"], ["id", "panel-upload", "role", "tabpanel", 1, "upload-section"], ["id", "panel-url", "role", "tabpanel", 1, "url-section"], ["id", "panel-icon", "role", "tabpanel", 1, "icon-section"], ["id", "panel-provider", "role", "tabpanel", 1, "provider-section"], [1, "action-buttons"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["Variant", "error", "Dismissible", "", 3, "Dismissed", "Message"], ["aria-hidden", "true"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["type", "file", "accept", "image/png,image/jpeg,image/jpg,image/gif,image/webp", 2, "display", "none", 3, "change"], [1, "upload-btn", 3, "click"], [1, "upload-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], [1, "selected-file"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-image"], ["aria-label", "Remove selected file", 1, "remove-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["for", "imageUrl"], ["type", "text", "id", "imageUrl", "placeholder", "https://example.com/avatar.jpg", 1, "url-input", 3, "ngModelChange", "input", "ngModel"], [1, "url-info"], [1, "icon-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search icons by name...", "aria-label", "Search icons", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Clear search", 1, "mj-search-clear"], [1, "icon-filter-info"], [1, "icon-categories-container"], ["Variant", "no-results", "Size", "compact", "Title", "No icons found", "Message", "Try a different search term"], ["aria-label", "Clear search", 1, "mj-search-clear", 3, "click"], [1, "icon-category"], [1, "category-title"], ["role", "radiogroup", 1, "icon-grid"], ["role", "radio", 1, "icon-option", 3, "selected", "title"], ["role", "radio", 1, "icon-option", 3, "click", "title"], [1, "provider-info"], [1, "sync-btn", 3, "click", "disabled"], [1, "provider-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-lightbulb"], [1, "provider-divider"], [1, "revert-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function UserProfileSettingsComponent_Template(rf, ctx) { if (rf & 1) {
757
739
  i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h3");
758
740
  i0.ɵɵtext(3, "Avatar Settings");
759
741
  i0.ɵɵelementEnd();
760
742
  i0.ɵɵelementStart(4, "p", 3);
761
743
  i0.ɵɵtext(5, "Customize your profile picture with an image, URL, or icon");
762
744
  i0.ɵɵelementEnd()();
763
- i0.ɵɵconditionalCreate(6, UserProfileSettingsComponent_Conditional_6_Template, 6, 1, "div", 4);
764
- i0.ɵɵconditionalCreate(7, UserProfileSettingsComponent_Conditional_7_Template, 4, 0, "div", 5);
745
+ i0.ɵɵconditionalCreate(6, UserProfileSettingsComponent_Conditional_6_Template, 1, 1, "mj-alert", 4);
746
+ i0.ɵɵconditionalCreate(7, UserProfileSettingsComponent_Conditional_7_Template, 1, 0, "mj-alert", 5);
765
747
  i0.ɵɵelementStart(8, "div", 6)(9, "div", 7);
766
748
  i0.ɵɵtext(10, "Preview");
767
749
  i0.ɵɵelementEnd();
@@ -839,11 +821,11 @@ export class UserProfileSettingsComponent extends BaseAngularComponent {
839
821
  i0.ɵɵconditional(ctx.isSaving ? 39 : 40);
840
822
  i0.ɵɵadvance(2);
841
823
  i0.ɵɵproperty("disabled", ctx.isSaving);
842
- } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n\n\n\n.profile-header[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.profile-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.profile-header[_ngcontent-%COMP%] .description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.alert[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 1rem;\n}\n\n.alert[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.alert.alert-error[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.alert.alert-success[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n\n\n\n\n.avatar-preview-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container[_ngcontent-%COMP%] {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--mj-bg-surface);\n border: 3px solid var(--mj-border-strong);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container[_ngcontent-%COMP%]:has(.preview-image), \n.preview-container[_ngcontent-%COMP%]:has(.preview-icon) {\n border-color: var(--mj-brand-primary);\n}\n\n.preview-image[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.preview-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-brand-primary);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--mj-text-muted);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n.preview-placeholder[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--mj-border-strong);\n}\n\n\n\n\n\n.upload-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.upload-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.upload-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.upload-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.selected-file[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.selected-file[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s, background 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: inherit;\n}\n\n\n\n\n\n.url-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.url-input[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 1rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.url-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.url-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.url-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.url-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n.icon-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 2.75rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.mj-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n border-radius: 9999px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear[_ngcontent-%COMP%]:hover {\n color: var(--mj-bg-surface);\n background: var(--mj-brand-primary);\n}\n\n.icon-filter-info[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category[_ngcontent-%COMP%] .category-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option[_ngcontent-%COMP%] {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.icon-option[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.icon-option[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.icon-option[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.icon-option.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-bg-surface);\n}\n\n\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n color: var(--mj-border-strong);\n margin-bottom: 1rem;\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-muted);\n margin: 0;\n}\n\n\n\n\n\n.provider-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.sync-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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: 48px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n}\n\n.provider-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider[_ngcontent-%COMP%] {\n border: none;\n border-top: 1px solid var(--mj-border-strong);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: 9999px;\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}\n\n.revert-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n\n\n\n\n.mj-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: 9999px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.mj-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-btn-primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%] {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--mj-text-muted);\n padding: 0.5rem;\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n}\n\n.mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_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@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n }\n\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 300px;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .action-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section[_ngcontent-%COMP%] {\n padding: 0.5rem 0;\n }\n\n .sync-btn[_ngcontent-%COMP%], \n .revert-btn[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search[_ngcontent-%COMP%] {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}"] });
824
+ } }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel, i4.MJButtonDirective, i4.MJEmptyStateComponent, i4.MJAlertComponent], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n\n\n\n\n.profile-header[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.profile-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.profile-header[_ngcontent-%COMP%] .description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-muted);\n}\n\n\n\n\n\n.avatar-preview-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container[_ngcontent-%COMP%] {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--mj-bg-surface);\n border: 3px solid var(--mj-border-strong);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container[_ngcontent-%COMP%]:has(.preview-image), \n.preview-container[_ngcontent-%COMP%]:has(.preview-icon) {\n border-color: var(--mj-brand-primary);\n}\n\n.preview-image[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.preview-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--mj-brand-primary);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--mj-text-muted);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n.preview-placeholder[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--mj-border-strong);\n}\n\n\n\n\n\n.upload-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn[_ngcontent-%COMP%]:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.upload-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.upload-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.upload-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.selected-file[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.selected-file[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s, background 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%]:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: inherit;\n}\n\n\n\n\n\n.url-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.url-input[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 1rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.url-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.url-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.url-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.url-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n\n\n\n\n.icon-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 2.75rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--mj-text-muted);\n}\n\n.mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.mj-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n border-radius: 9999px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear[_ngcontent-%COMP%]:hover {\n color: var(--mj-bg-surface);\n background: var(--mj-brand-primary);\n}\n\n.icon-filter-info[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category[_ngcontent-%COMP%] .category-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option[_ngcontent-%COMP%] {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.icon-option[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.icon-option[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n}\n\n.icon-option[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.icon-option.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-bg-surface);\n}\n\n\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n\n\n\n\n.provider-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.sync-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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: 48px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n}\n\n.provider-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-status-warning);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider[_ngcontent-%COMP%] {\n border: none;\n border-top: 1px solid var(--mj-border-strong);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: 9999px;\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}\n\n.revert-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n\n\n\n\n\n\n\n\n\n\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_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@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n }\n\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 300px;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .action-buttons[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section[_ngcontent-%COMP%] {\n padding: 0.5rem 0;\n }\n\n .sync-btn[_ngcontent-%COMP%], \n .revert-btn[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search[_ngcontent-%COMP%] {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}"] });
843
825
  }
844
826
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserProfileSettingsComponent, [{
845
827
  type: Component,
846
- args: [{ standalone: false, selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <!-- Header Section -->\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <div class=\"alert alert-error\" role=\"alert\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"close-btn\" (click)=\"errorMessage = ''\" aria-label=\"Dismiss error\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <div class=\"alert alert-success\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-check-circle\" aria-hidden=\"true\"></i>\n <span>Avatar updated successfully!</span>\n </div>\n }\n\n <!-- Avatar Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\" aria-hidden=\"true\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\" role=\"tablist\" aria-label=\"Avatar customization options\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'upload'\"\n aria-controls=\"panel-upload\"\n >\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'url'\"\n aria-controls=\"panel-url\"\n >\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'icon'\"\n aria-controls=\"panel-icon\"\n >\n <i class=\"fa-solid fa-icons\" aria-hidden=\"true\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'provider'\"\n aria-controls=\"panel-provider\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\" id=\"panel-upload\" role=\"tabpanel\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Max 200KB - PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\" aria-hidden=\"true\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\" aria-label=\"Remove selected file\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\" id=\"panel-url\" role=\"tabpanel\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\" id=\"panel-icon\" role=\"tabpanel\">\n <!-- Icon Search -->\n <div class=\"icon-search-container\">\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search icons by name...\"\n [value]=\"iconSearchTerm\"\n (input)=\"onIconSearchChange($event)\"\n aria-label=\"Search icons\"\n />\n @if (iconSearchTerm) {\n <button\n class=\"mj-search-clear\"\n (click)=\"clearIconSearch()\"\n aria-label=\"Clear search\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"icon-filter-info\">\n {{ totalFilteredIcons }} icon{{ totalFilteredIcons !== 1 ? 's' : '' }} found\n </div>\n </div>\n\n <!-- Icon Categories -->\n <div class=\"icon-categories-container\">\n @if (filteredIconCategories.length > 0) {\n @for (category of filteredIconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\" role=\"radiogroup\" [attr.aria-label]=\"category.name + ' icons'\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"extractIconName(icon)\"\n role=\"radio\"\n [attr.aria-checked]=\"isIconSelected(icon)\"\n [attr.aria-label]=\"extractIconName(icon) + ' icon'\"\n >\n <i [class]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No icons found</p>\n <p class=\"empty-subtext\">Try a different search term</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\" id=\"panel-provider\" role=\"tabpanel\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\" aria-hidden=\"true\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <hr class=\"provider-divider\" />\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n mjButton variant=\"primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n mjButton\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* =============================================================================\n User Profile Settings Component\n Using MJ Design Tokens\n ============================================================================= */\n\n/* Host element must be scrollable */\n:host {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* -----------------------------------------------------------------------------\n Header Section\n ----------------------------------------------------------------------------- */\n.profile-header {\n margin-bottom: 1.5rem;\n}\n\n.profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.profile-header .description {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-muted);\n}\n\n/* -----------------------------------------------------------------------------\n Alert Messages\n ----------------------------------------------------------------------------- */\n.alert {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.alert i {\n flex-shrink: 0;\n font-size: 1rem;\n}\n\n.alert span {\n flex: 1;\n}\n\n.alert .close-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.alert .close-btn:hover {\n opacity: 1;\n}\n\n.alert.alert-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.alert.alert-success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Avatar Preview Section\n ----------------------------------------------------------------------------- */\n.avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n}\n\n.preview-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--mj-bg-surface);\n border: 3px solid var(--mj-border-strong);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container:has(.preview-image),\n.preview-container:has(.preview-icon) {\n border-color: var(--mj-brand-primary);\n}\n\n.preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.preview-icon {\n font-size: 3.5rem;\n color: var(--mj-brand-primary);\n}\n\n.preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--mj-text-muted);\n}\n\n.preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.preview-placeholder span {\n font-size: 0.875rem;\n}\n\n/* -----------------------------------------------------------------------------\n Tab Navigation\n ----------------------------------------------------------------------------- */\n.tab-navigation {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn i {\n font-size: 1rem;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* -----------------------------------------------------------------------------\n Tab Content\n ----------------------------------------------------------------------------- */\n.tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Upload Section\n ----------------------------------------------------------------------------- */\n.upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:hover {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.upload-btn i {\n font-size: 1rem;\n}\n\n.upload-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.upload-info i {\n color: var(--mj-brand-primary);\n}\n\n.selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.selected-file span {\n flex: 1;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s, background 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file .remove-btn:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* -----------------------------------------------------------------------------\n URL Section\n ----------------------------------------------------------------------------- */\n.url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.url-input {\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 1rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.url-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.url-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.url-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.url-info i {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Icon Section (with Search)\n ----------------------------------------------------------------------------- */\n.icon-section {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n/* Search Component */\n.mj-search {\n position: relative;\n width: 100%;\n}\n\n.mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search-input {\n width: 100%;\n padding: 0.875rem 2.75rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-search-clear {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n border-radius: 9999px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear:hover {\n color: var(--mj-bg-surface);\n background: var(--mj-brand-primary);\n}\n\n.icon-filter-info {\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category .category-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option i {\n font-size: 1.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.icon-option:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.icon-option:hover i {\n color: var(--mj-brand-primary);\n}\n\n.icon-option:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.icon-option.selected i {\n color: var(--mj-bg-surface);\n}\n\n/* Custom Scrollbar for Icon Section */\n.icon-categories-container::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n/* Empty State */\n.empty-state {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state .empty-icon {\n font-size: 3rem;\n color: var(--mj-border-strong);\n margin-bottom: 1rem;\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-muted);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Provider Section\n ----------------------------------------------------------------------------- */\n.provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info p {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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: 48px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.sync-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn i {\n font-size: 1.2rem;\n}\n\n.provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note i {\n color: var(--mj-status-warning);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider {\n border: none;\n border-top: 1px solid var(--mj-border-strong);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: 9999px;\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}\n\n.revert-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons\n ----------------------------------------------------------------------------- */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Button System\n ----------------------------------------------------------------------------- */\n.mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: 9999px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.mj-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.mj-btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.mj-btn-secondary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-secondary:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-ghost {\n background: transparent;\n color: var(--mj-text-muted);\n padding: 0.5rem;\n}\n\n.mj-btn-ghost:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n}\n\n.mj-btn-ghost:active:not(:disabled) {\n background: var(--mj-brand-primary);\n}\n\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput: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/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Responsive Design - Mobile First\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container {\n max-height: 300px;\n }\n\n .action-buttons {\n flex-direction: column;\n }\n\n .action-buttons .mj-btn {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section {\n padding: 0.5rem 0;\n }\n\n .sync-btn,\n .revert-btn {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings {\n padding: 2rem;\n }\n\n .icon-categories-container {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}\n"] }]
828
+ args: [{ standalone: false, selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <!-- Header Section -->\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <mj-alert Variant=\"error\" [Message]=\"errorMessage\" Dismissible (Dismissed)=\"errorMessage = ''\" />\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <mj-alert Variant=\"success\" Message=\"Avatar updated successfully!\" />\n }\n\n <!-- Avatar Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\" aria-hidden=\"true\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\" role=\"tablist\" aria-label=\"Avatar customization options\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'upload'\"\n aria-controls=\"panel-upload\"\n >\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'url'\"\n aria-controls=\"panel-url\"\n >\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'icon'\"\n aria-controls=\"panel-icon\"\n >\n <i class=\"fa-solid fa-icons\" aria-hidden=\"true\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'provider'\"\n aria-controls=\"panel-provider\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\" id=\"panel-upload\" role=\"tabpanel\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Max 200KB - PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\" aria-hidden=\"true\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\" aria-label=\"Remove selected file\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\" id=\"panel-url\" role=\"tabpanel\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\" id=\"panel-icon\" role=\"tabpanel\">\n <!-- Icon Search -->\n <div class=\"icon-search-container\">\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search icons by name...\"\n [value]=\"iconSearchTerm\"\n (input)=\"onIconSearchChange($event)\"\n aria-label=\"Search icons\"\n />\n @if (iconSearchTerm) {\n <button\n class=\"mj-search-clear\"\n (click)=\"clearIconSearch()\"\n aria-label=\"Clear search\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"icon-filter-info\">\n {{ totalFilteredIcons }} icon{{ totalFilteredIcons !== 1 ? 's' : '' }} found\n </div>\n </div>\n\n <!-- Icon Categories -->\n <div class=\"icon-categories-container\">\n @if (filteredIconCategories.length > 0) {\n @for (category of filteredIconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\" role=\"radiogroup\" [attr.aria-label]=\"category.name + ' icons'\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"extractIconName(icon)\"\n role=\"radio\"\n [attr.aria-checked]=\"isIconSelected(icon)\"\n [attr.aria-label]=\"extractIconName(icon) + ' icon'\"\n >\n <i [class]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Size=\"compact\"\n Title=\"No icons found\"\n Message=\"Try a different search term\" />\n }\n </div>\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\" id=\"panel-provider\" role=\"tabpanel\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\" aria-hidden=\"true\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <hr class=\"provider-divider\" />\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n mjButton variant=\"primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n mjButton\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* =============================================================================\n User Profile Settings Component\n Using MJ Design Tokens\n ============================================================================= */\n\n/* Host element must be scrollable */\n:host {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* -----------------------------------------------------------------------------\n Header Section\n ----------------------------------------------------------------------------- */\n.profile-header {\n margin-bottom: 1.5rem;\n}\n\n.profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.profile-header .description {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-muted);\n}\n\n/* -----------------------------------------------------------------------------\n Avatar Preview Section\n ----------------------------------------------------------------------------- */\n.avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n}\n\n.preview-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--mj-bg-surface);\n border: 3px solid var(--mj-border-strong);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container:has(.preview-image),\n.preview-container:has(.preview-icon) {\n border-color: var(--mj-brand-primary);\n}\n\n.preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.preview-icon {\n font-size: 3.5rem;\n color: var(--mj-brand-primary);\n}\n\n.preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--mj-text-muted);\n}\n\n.preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.preview-placeholder span {\n font-size: 0.875rem;\n}\n\n/* -----------------------------------------------------------------------------\n Tab Navigation\n ----------------------------------------------------------------------------- */\n.tab-navigation {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn i {\n font-size: 1rem;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* -----------------------------------------------------------------------------\n Tab Content\n ----------------------------------------------------------------------------- */\n.tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Upload Section\n ----------------------------------------------------------------------------- */\n.upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:hover {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.upload-btn i {\n font-size: 1rem;\n}\n\n.upload-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.upload-info i {\n color: var(--mj-brand-primary);\n}\n\n.selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.selected-file span {\n flex: 1;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s, background 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file .remove-btn:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* -----------------------------------------------------------------------------\n URL Section\n ----------------------------------------------------------------------------- */\n.url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.url-input {\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 1rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.url-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.url-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.url-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.url-info i {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Icon Section (with Search)\n ----------------------------------------------------------------------------- */\n.icon-section {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n/* Search Component */\n.mj-search {\n position: relative;\n width: 100%;\n}\n\n.mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search-input {\n width: 100%;\n padding: 0.875rem 2.75rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-search-clear {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n border-radius: 9999px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear:hover {\n color: var(--mj-bg-surface);\n background: var(--mj-brand-primary);\n}\n\n.icon-filter-info {\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category .category-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option i {\n font-size: 1.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.icon-option:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.icon-option:hover i {\n color: var(--mj-brand-primary);\n}\n\n.icon-option:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.icon-option.selected i {\n color: var(--mj-bg-surface);\n}\n\n/* Custom Scrollbar for Icon Section */\n.icon-categories-container::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n/* -----------------------------------------------------------------------------\n Provider Section\n ----------------------------------------------------------------------------- */\n.provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info p {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\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: 48px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.sync-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn i {\n font-size: 1.2rem;\n}\n\n.provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note i {\n color: var(--mj-status-warning);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider {\n border: none;\n border-top: 1px solid var(--mj-border-strong);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: 9999px;\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}\n\n.revert-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons\n ----------------------------------------------------------------------------- */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Buttons \u2014 the action buttons use the mjButton directive (variant/size inputs),\n which owns their appearance app-wide. No component-scoped .mj-btn overrides\n (they fork the standard styling). Layout-only tweaks live with their container.\n ----------------------------------------------------------------------------- */\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput: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/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Responsive Design - Mobile First\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container {\n max-height: 300px;\n }\n\n .action-buttons {\n flex-direction: column;\n }\n\n .action-buttons button {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section {\n padding: 0.5rem 0;\n }\n\n .sync-btn,\n .revert-btn {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings {\n padding: 2rem;\n }\n\n .icon-categories-container {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}\n"] }]
847
829
  }], () => [{ type: i1.UserAvatarService }, { type: i2.SharedService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], null); })();
848
830
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber: 24 }); })();
849
831
  //# sourceMappingURL=user-profile-settings.component.js.map