@avora-labs/meta-forge 1.0.5 → 1.0.6

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 (20) hide show
  1. package/README.md +112 -63
  2. package/fesm2022/{avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs → avora-labs-meta-forge-amf-auth-shell.component-FCubZyZ1.mjs} +57 -57
  3. package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-FCubZyZ1.mjs.map +1 -0
  4. package/fesm2022/{avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs → avora-labs-meta-forge-contact-support.page-CgcSAr0x.mjs} +146 -146
  5. package/fesm2022/avora-labs-meta-forge-contact-support.page-CgcSAr0x.mjs.map +1 -0
  6. package/fesm2022/{avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs → avora-labs-meta-forge-forgot-password.page-CWdWX-mj.mjs} +238 -238
  7. package/fesm2022/avora-labs-meta-forge-forgot-password.page-CWdWX-mj.mjs.map +1 -0
  8. package/fesm2022/{avora-labs-meta-forge-login.page-etTr5NqJ.mjs → avora-labs-meta-forge-login.page-LCW-ofz1.mjs} +74 -74
  9. package/fesm2022/avora-labs-meta-forge-login.page-LCW-ofz1.mjs.map +1 -0
  10. package/fesm2022/avora-labs-meta-forge.mjs +1995 -1995
  11. package/fesm2022/avora-labs-meta-forge.mjs.map +1 -1
  12. package/package.json +3 -1
  13. package/styles/_palettes.scss +84 -84
  14. package/styles/_themes.scss +96 -96
  15. package/styles/_variables.scss +56 -56
  16. package/styles/styles.scss +295 -295
  17. package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs.map +0 -1
  18. package/fesm2022/avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs.map +0 -1
  19. package/fesm2022/avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs.map +0 -1
  20. package/fesm2022/avora-labs-meta-forge-login.page-etTr5NqJ.mjs.map +0 -1
@@ -1,296 +1,296 @@
1
- /* ═══════════════════════════════════════════════════════════════
2
- AvoraMetaForge — Glass Design System Global Styles
3
- ═══════════════════════════════════════════════════════════════ */
4
-
5
- @use 'variables' as *;
6
- @use 'themes' as *;
7
-
8
- @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Outfit:wght@100..900&display=swap');
9
-
10
- /* ─── Reset ─── */
11
- * {
12
- box-sizing: border-box;
13
- margin: 0;
14
- padding: 0;
15
- }
16
-
17
- /* ─── Root height chain — required for auth page scrolling ─── */
18
- html {
19
- height: 100%;
20
- }
21
-
22
- /* ─── Body ─── */
23
- body {
24
- font-family: 'Inter', system-ui, -apple-system, sans-serif;
25
- background-color: var(--app-bg);
26
- color: var(--app-text);
27
- line-height: 1.5;
28
- -webkit-font-smoothing: antialiased;
29
- -moz-osx-font-smoothing: grayscale;
30
- height: 100%;
31
- overflow-x: hidden; /* allow vertical scroll; block horizontal */
32
- }
33
-
34
- /* ─── Typography ─── */
35
- h1,
36
- h2,
37
- h3,
38
- h4,
39
- h5,
40
- h6 {
41
- font-family: 'Outfit', sans-serif;
42
- font-weight: 700;
43
- color: var(--app-text);
44
- }
45
-
46
- a {
47
- color: var(--app-primary);
48
- text-decoration: none;
49
- transition: color var(--transition-fast);
50
- }
51
-
52
- a:hover {
53
- color: var(--app-primary-hover);
54
- }
55
-
56
- button {
57
- font-family: inherit;
58
- cursor: pointer;
59
- }
60
-
61
- /* ─── Scrollbar ─── */
62
- ::-webkit-scrollbar {
63
- width: 6px;
64
- height: 6px;
65
- }
66
-
67
- ::-webkit-scrollbar-track {
68
- background: transparent;
69
- }
70
-
71
- ::-webkit-scrollbar-thumb {
72
- background: rgba(255, 255, 255, 0.1);
73
- border-radius: 3px;
74
- }
75
-
76
- ::-webkit-scrollbar-thumb:hover {
77
- background: rgba(255, 255, 255, 0.2);
78
- }
79
-
80
- /* ═══════════════════════════════════════════════════════════════
81
- Glass Utilities
82
- ═══════════════════════════════════════════════════════════════ */
83
-
84
- .glass {
85
- background: var(--glass-bg);
86
- backdrop-filter: blur(var(--glass-blur));
87
- -webkit-backdrop-filter: blur(var(--glass-blur));
88
- border: 1px solid var(--glass-border);
89
- }
90
-
91
- .card {
92
- background: var(--glass-bg);
93
- backdrop-filter: blur(var(--glass-blur));
94
- -webkit-backdrop-filter: blur(var(--glass-blur));
95
- border: 1px solid var(--glass-border);
96
- border-radius: 16px;
97
- padding: 24px;
98
- box-shadow: var(--glass-shadow-sm);
99
- transition: all var(--transition-smooth);
100
- }
101
-
102
- .card:hover {
103
- background: var(--glass-bg-hover);
104
- border-color: var(--glass-border-light);
105
- box-shadow: var(--glass-shadow);
106
- transform: translateY(-2px);
107
- }
108
-
109
- /* ─── Buttons ─── */
110
- .btn-primary {
111
- background: linear-gradient(135deg, var(--app-primary), var(--app-accent));
112
- color: var(--app-on-primary);
113
- border: none;
114
- padding: 10px 20px;
115
- border-radius: 10px;
116
- font-weight: 600;
117
- transition: all var(--transition-smooth);
118
- position: relative;
119
- overflow: hidden;
120
- }
121
-
122
- .btn-primary::after {
123
- content: '';
124
- position: absolute;
125
- top: 0;
126
- left: -100%;
127
- right: 0;
128
- bottom: 0;
129
- width: 200%;
130
- background: linear-gradient(90deg,
131
- transparent 0%,
132
- rgba(255, 255, 255, 0.1) 50%,
133
- transparent 100%);
134
- transition: left 0.5s ease;
135
- }
136
-
137
- .btn-primary:hover {
138
- transform: translateY(-2px);
139
- box-shadow: 0 8px 24px -4px var(--app-glow);
140
- }
141
-
142
- .btn-primary:hover::after {
143
- left: 100%;
144
- }
145
-
146
- /* ═══════════════════════════════════════════════════════════════
147
- Keyframe Animations
148
- ═══════════════════════════════════════════════════════════════ */
149
-
150
- @keyframes fadeInUp {
151
- from {
152
- opacity: 0;
153
- transform: translateY(20px);
154
- }
155
-
156
- to {
157
- opacity: 1;
158
- transform: translateY(0);
159
- }
160
- }
161
-
162
- @keyframes fadeIn {
163
- from {
164
- opacity: 0;
165
- }
166
-
167
- to {
168
- opacity: 1;
169
- }
170
- }
171
-
172
- @keyframes shimmer {
173
- 0% {
174
- background-position: -200% center;
175
- }
176
-
177
- 100% {
178
- background-position: 200% center;
179
- }
180
- }
181
-
182
- @keyframes gradientShift {
183
-
184
- 0%,
185
- 100% {
186
- background-position: 0% 50%;
187
- }
188
-
189
- 25% {
190
- background-position: 50% 0%;
191
- }
192
-
193
- 50% {
194
- background-position: 100% 50%;
195
- }
196
-
197
- 75% {
198
- background-position: 50% 100%;
199
- }
200
- }
201
-
202
- @keyframes pulseGlow {
203
-
204
- 0%,
205
- 100% {
206
- box-shadow: 0 0 20px var(--app-glow);
207
- }
208
-
209
- 50% {
210
- box-shadow: 0 0 40px var(--app-glow), 0 0 60px var(--app-glow);
211
- }
212
- }
213
-
214
- @keyframes float {
215
-
216
- 0%,
217
- 100% {
218
- transform: translateY(0);
219
- }
220
-
221
- 50% {
222
- transform: translateY(-10px);
223
- }
224
- }
225
-
226
- @keyframes slideInDown {
227
- from {
228
- opacity: 0;
229
- transform: translateY(-10px) scale(0.95);
230
- }
231
-
232
- to {
233
- opacity: 1;
234
- transform: translateY(0) scale(1);
235
- }
236
- }
237
-
238
- @keyframes blobMove1 {
239
-
240
- 0%,
241
- 100% {
242
- transform: translate(0, 0) scale(1);
243
- }
244
-
245
- 25% {
246
- transform: translate(30px, -50px) scale(1.1);
247
- }
248
-
249
- 50% {
250
- transform: translate(-20px, 20px) scale(0.9);
251
- }
252
-
253
- 75% {
254
- transform: translate(50px, 30px) scale(1.05);
255
- }
256
- }
257
-
258
- @keyframes blobMove2 {
259
-
260
- 0%,
261
- 100% {
262
- transform: translate(0, 0) scale(1);
263
- }
264
-
265
- 25% {
266
- transform: translate(-40px, 30px) scale(0.95);
267
- }
268
-
269
- 50% {
270
- transform: translate(30px, -40px) scale(1.1);
271
- }
272
-
273
- 75% {
274
- transform: translate(-20px, -30px) scale(1);
275
- }
276
- }
277
-
278
- @keyframes blobMove3 {
279
-
280
- 0%,
281
- 100% {
282
- transform: translate(0, 0) scale(1.05);
283
- }
284
-
285
- 25% {
286
- transform: translate(20px, 40px) scale(1);
287
- }
288
-
289
- 50% {
290
- transform: translate(-40px, -20px) scale(1.1);
291
- }
292
-
293
- 75% {
294
- transform: translate(30px, -30px) scale(0.95);
295
- }
1
+ /* ═══════════════════════════════════════════════════════════════
2
+ AvoraMetaForge — Glass Design System Global Styles
3
+ ═══════════════════════════════════════════════════════════════ */
4
+
5
+ @use 'variables' as *;
6
+ @use 'themes' as *;
7
+
8
+ @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Outfit:wght@100..900&display=swap');
9
+
10
+ /* ─── Reset ─── */
11
+ * {
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ }
16
+
17
+ /* ─── Root height chain — required for auth page scrolling ─── */
18
+ html {
19
+ height: 100%;
20
+ }
21
+
22
+ /* ─── Body ─── */
23
+ body {
24
+ font-family: 'Inter', system-ui, -apple-system, sans-serif;
25
+ background-color: var(--app-bg);
26
+ color: var(--app-text);
27
+ line-height: 1.5;
28
+ -webkit-font-smoothing: antialiased;
29
+ -moz-osx-font-smoothing: grayscale;
30
+ height: 100%;
31
+ overflow-x: hidden; /* allow vertical scroll; block horizontal */
32
+ }
33
+
34
+ /* ─── Typography ─── */
35
+ h1,
36
+ h2,
37
+ h3,
38
+ h4,
39
+ h5,
40
+ h6 {
41
+ font-family: 'Outfit', sans-serif;
42
+ font-weight: 700;
43
+ color: var(--app-text);
44
+ }
45
+
46
+ a {
47
+ color: var(--app-primary);
48
+ text-decoration: none;
49
+ transition: color var(--transition-fast);
50
+ }
51
+
52
+ a:hover {
53
+ color: var(--app-primary-hover);
54
+ }
55
+
56
+ button {
57
+ font-family: inherit;
58
+ cursor: pointer;
59
+ }
60
+
61
+ /* ─── Scrollbar ─── */
62
+ ::-webkit-scrollbar {
63
+ width: 6px;
64
+ height: 6px;
65
+ }
66
+
67
+ ::-webkit-scrollbar-track {
68
+ background: transparent;
69
+ }
70
+
71
+ ::-webkit-scrollbar-thumb {
72
+ background: rgba(255, 255, 255, 0.1);
73
+ border-radius: 3px;
74
+ }
75
+
76
+ ::-webkit-scrollbar-thumb:hover {
77
+ background: rgba(255, 255, 255, 0.2);
78
+ }
79
+
80
+ /* ═══════════════════════════════════════════════════════════════
81
+ Glass Utilities
82
+ ═══════════════════════════════════════════════════════════════ */
83
+
84
+ .glass {
85
+ background: var(--glass-bg);
86
+ backdrop-filter: blur(var(--glass-blur));
87
+ -webkit-backdrop-filter: blur(var(--glass-blur));
88
+ border: 1px solid var(--glass-border);
89
+ }
90
+
91
+ .card {
92
+ background: var(--glass-bg);
93
+ backdrop-filter: blur(var(--glass-blur));
94
+ -webkit-backdrop-filter: blur(var(--glass-blur));
95
+ border: 1px solid var(--glass-border);
96
+ border-radius: 16px;
97
+ padding: 24px;
98
+ box-shadow: var(--glass-shadow-sm);
99
+ transition: all var(--transition-smooth);
100
+ }
101
+
102
+ .card:hover {
103
+ background: var(--glass-bg-hover);
104
+ border-color: var(--glass-border-light);
105
+ box-shadow: var(--glass-shadow);
106
+ transform: translateY(-2px);
107
+ }
108
+
109
+ /* ─── Buttons ─── */
110
+ .btn-primary {
111
+ background: linear-gradient(135deg, var(--app-primary), var(--app-accent));
112
+ color: var(--app-on-primary);
113
+ border: none;
114
+ padding: 10px 20px;
115
+ border-radius: 10px;
116
+ font-weight: 600;
117
+ transition: all var(--transition-smooth);
118
+ position: relative;
119
+ overflow: hidden;
120
+ }
121
+
122
+ .btn-primary::after {
123
+ content: '';
124
+ position: absolute;
125
+ top: 0;
126
+ left: -100%;
127
+ right: 0;
128
+ bottom: 0;
129
+ width: 200%;
130
+ background: linear-gradient(90deg,
131
+ transparent 0%,
132
+ rgba(255, 255, 255, 0.1) 50%,
133
+ transparent 100%);
134
+ transition: left 0.5s ease;
135
+ }
136
+
137
+ .btn-primary:hover {
138
+ transform: translateY(-2px);
139
+ box-shadow: 0 8px 24px -4px var(--app-glow);
140
+ }
141
+
142
+ .btn-primary:hover::after {
143
+ left: 100%;
144
+ }
145
+
146
+ /* ═══════════════════════════════════════════════════════════════
147
+ Keyframe Animations
148
+ ═══════════════════════════════════════════════════════════════ */
149
+
150
+ @keyframes fadeInUp {
151
+ from {
152
+ opacity: 0;
153
+ transform: translateY(20px);
154
+ }
155
+
156
+ to {
157
+ opacity: 1;
158
+ transform: translateY(0);
159
+ }
160
+ }
161
+
162
+ @keyframes fadeIn {
163
+ from {
164
+ opacity: 0;
165
+ }
166
+
167
+ to {
168
+ opacity: 1;
169
+ }
170
+ }
171
+
172
+ @keyframes shimmer {
173
+ 0% {
174
+ background-position: -200% center;
175
+ }
176
+
177
+ 100% {
178
+ background-position: 200% center;
179
+ }
180
+ }
181
+
182
+ @keyframes gradientShift {
183
+
184
+ 0%,
185
+ 100% {
186
+ background-position: 0% 50%;
187
+ }
188
+
189
+ 25% {
190
+ background-position: 50% 0%;
191
+ }
192
+
193
+ 50% {
194
+ background-position: 100% 50%;
195
+ }
196
+
197
+ 75% {
198
+ background-position: 50% 100%;
199
+ }
200
+ }
201
+
202
+ @keyframes pulseGlow {
203
+
204
+ 0%,
205
+ 100% {
206
+ box-shadow: 0 0 20px var(--app-glow);
207
+ }
208
+
209
+ 50% {
210
+ box-shadow: 0 0 40px var(--app-glow), 0 0 60px var(--app-glow);
211
+ }
212
+ }
213
+
214
+ @keyframes float {
215
+
216
+ 0%,
217
+ 100% {
218
+ transform: translateY(0);
219
+ }
220
+
221
+ 50% {
222
+ transform: translateY(-10px);
223
+ }
224
+ }
225
+
226
+ @keyframes slideInDown {
227
+ from {
228
+ opacity: 0;
229
+ transform: translateY(-10px) scale(0.95);
230
+ }
231
+
232
+ to {
233
+ opacity: 1;
234
+ transform: translateY(0) scale(1);
235
+ }
236
+ }
237
+
238
+ @keyframes blobMove1 {
239
+
240
+ 0%,
241
+ 100% {
242
+ transform: translate(0, 0) scale(1);
243
+ }
244
+
245
+ 25% {
246
+ transform: translate(30px, -50px) scale(1.1);
247
+ }
248
+
249
+ 50% {
250
+ transform: translate(-20px, 20px) scale(0.9);
251
+ }
252
+
253
+ 75% {
254
+ transform: translate(50px, 30px) scale(1.05);
255
+ }
256
+ }
257
+
258
+ @keyframes blobMove2 {
259
+
260
+ 0%,
261
+ 100% {
262
+ transform: translate(0, 0) scale(1);
263
+ }
264
+
265
+ 25% {
266
+ transform: translate(-40px, 30px) scale(0.95);
267
+ }
268
+
269
+ 50% {
270
+ transform: translate(30px, -40px) scale(1.1);
271
+ }
272
+
273
+ 75% {
274
+ transform: translate(-20px, -30px) scale(1);
275
+ }
276
+ }
277
+
278
+ @keyframes blobMove3 {
279
+
280
+ 0%,
281
+ 100% {
282
+ transform: translate(0, 0) scale(1.05);
283
+ }
284
+
285
+ 25% {
286
+ transform: translate(20px, 40px) scale(1);
287
+ }
288
+
289
+ 50% {
290
+ transform: translate(-40px, -20px) scale(1.1);
291
+ }
292
+
293
+ 75% {
294
+ transform: translate(30px, -30px) scale(0.95);
295
+ }
296
296
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs","sources":["../../../projects/avora-meta-forge/src/lib/avora-meta-forge/renderers/auth/amf-auth-shell.component.ts"],"sourcesContent":["/**\r\n * AvoraMetaForge — Auth Shell Component\r\n *\r\n * A reusable full-page auth card renderer providing the glassmorphism\r\n * background and card layout shared by Login, Forgot Password, Contact\r\n * Support, and any other auth screen built with AvoraMetaForge.\r\n *\r\n * ## Responsiveness\r\n * This shell is fully mobile-first. On small screens (< 480 px) the card\r\n * fills the viewport and scrolls naturally; on larger screens it is a\r\n * centered floating card capped at `maxWidth`.\r\n *\r\n * ## Usage\r\n * <amf-auth-shell [brandName]=\"'MyApp'\" [brandTagline]=\"'Enterprise platform'\">\r\n * <!-- your form, steps, or custom HTML here -->\r\n * </amf-auth-shell>\r\n *\r\n * ## Icon system\r\n * Use <span class=\"ms\">lock</span> (Material Symbols Rounded) anywhere inside\r\n * the shell. The .ms class is globally defined in index.html.\r\n */\r\nimport { Component, Input } from '@angular/core';\r\n\r\n\r\n@Component({\r\n selector: 'amf-auth-shell',\r\n standalone: true,\r\n imports: [],\r\n template: `\r\n <div class=\"auth-page\">\r\n <!-- Animated Background Orbs -->\r\n <div class=\"bg-mesh\" aria-hidden=\"true\">\r\n <div class=\"orb orb-1\"></div>\r\n <div class=\"orb orb-2\"></div>\r\n <div class=\"orb orb-3\"></div>\r\n <div class=\"orb orb-4\"></div>\r\n </div>\r\n\r\n <div class=\"auth-scroll-wrapper\">\r\n <div class=\"auth-card\" [style.max-width]=\"maxWidth\">\r\n <!-- Brand Header -->\r\n <div class=\"brand\">\r\n <div class=\"brand-logo\">\r\n <svg viewBox=\"0 0 24 24\">\r\n <path d=\"M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5\"></path>\r\n </svg>\r\n </div>\r\n <h1>{{ brandName || 'AvoraMetaForge' }}</h1>\r\n <p>{{ brandTagline || 'The universal enterprise shell' }}</p>\r\n </div>\r\n\r\n <!-- Projected content slot -->\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n /* ─── Host fills the full slot given by router-outlet ─── */\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n }\r\n\r\n /* ─────────────────────────────────────────\r\n PAGE ROOT — fills parent, no overflow clip\r\n so the inner scroll wrapper can breathe\r\n ───────────────────────────────────────── */\r\n .auth-page {\r\n height: 100%;\r\n background: #0a0f1e;\r\n position: relative;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n /* ── Animated Background ── */\r\n .bg-mesh {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 0;\r\n overflow: hidden;\r\n pointer-events: none;\r\n }\r\n .orb {\r\n position: absolute;\r\n border-radius: 50%;\r\n filter: blur(100px);\r\n opacity: 0.4;\r\n will-change: transform;\r\n }\r\n .orb-1 {\r\n width: clamp(200px, 50vw, 600px);\r\n height: clamp(200px, 50vw, 600px);\r\n background: var(--app-gradient-1, radial-gradient(circle, #6366f1, transparent));\r\n top: -20%; right: -10%;\r\n animation: blobMove1 18s ease-in-out infinite;\r\n }\r\n .orb-2 {\r\n width: clamp(160px, 40vw, 500px);\r\n height: clamp(160px, 40vw, 500px);\r\n background: var(--app-gradient-2, radial-gradient(circle, #c084fc, transparent));\r\n bottom: -15%; left: -10%;\r\n animation: blobMove2 22s ease-in-out infinite;\r\n }\r\n .orb-3 {\r\n width: clamp(100px, 25vw, 300px);\r\n height: clamp(100px, 25vw, 300px);\r\n background: var(--app-gradient-3, radial-gradient(circle, #38bdf8, transparent));\r\n top: 50%; left: 50%;\r\n animation: blobMove3 20s ease-in-out infinite;\r\n }\r\n .orb-4 {\r\n width: clamp(80px, 16vw, 200px);\r\n height: clamp(80px, 16vw, 200px);\r\n background: var(--app-primary, #6366f1);\r\n top: 20%; left: 20%;\r\n opacity: 0.2;\r\n animation: blobMove1 25s ease-in-out infinite reverse;\r\n }\r\n\r\n /* ─────────────────────────────────────────\r\n SCROLL WRAPPER\r\n On mobile the card can exceed the screen\r\n height — this wrapper makes it scrollable.\r\n ───────────────────────────────────────── */\r\n .auth-scroll-wrapper {\r\n flex: 1;\r\n display: flex;\r\n align-items: flex-start; /* always flex-start; card uses margin:auto to self-center */\r\n justify-content: center;\r\n overflow-y: auto;\r\n overflow-x: hidden;\r\n padding: clamp(32px, 5vw, 56px) clamp(12px, 4vw, 24px);\r\n padding-top: max(env(safe-area-inset-top, 0px), clamp(32px, 5vw, 56px));\r\n padding-bottom: max(env(safe-area-inset-bottom, 0px), clamp(32px, 5vw, 56px));\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n /* ── Auth Card ── */\r\n .auth-card {\r\n background: rgba(255, 255, 255, 0.05);\r\n backdrop-filter: blur(40px);\r\n -webkit-backdrop-filter: blur(40px);\r\n width: 100%;\r\n max-width: 600px;\r\n /* margin:auto centers the card when there is spare space in the scroll wrapper,\r\n but unlike align-items:center it does NOT clip the top when the card overflows —\r\n the wrapper's padding-top stays visible as the user scrolls up. */\r\n margin: auto;\r\n /* Vertical padding kept tight to reduce card height; horizontal generous for width */\r\n padding: clamp(16px, 3vw, 24px) clamp(24px, 5vw, 52px);\r\n border-radius: clamp(14px, 2.5vw, 20px);\r\n border: 1px solid rgba(255, 255, 255, 0.1);\r\n box-shadow:\r\n 0 25px 50px -12px rgba(0, 0, 0, 0.5),\r\n 0 0 40px rgba(0, 0, 0, 0.2),\r\n inset 0 1px 0 rgba(255, 255, 255, 0.1);\r\n animation: fadeInUp 0.5s ease-out both;\r\n }\r\n .auth-card::before {\r\n content: '';\r\n position: absolute;\r\n top: -1px; left: -1px; right: -1px; bottom: -1px;\r\n border-radius: inherit;\r\n background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, transparent 50%, rgba(255,255,255,0.05) 100%);\r\n z-index: -1;\r\n pointer-events: none;\r\n }\r\n\r\n /* ── Brand — compact horizontal layout on wide screens ── */\r\n .brand {\r\n text-align: center;\r\n margin-bottom: clamp(10px, 2vw, 18px);\r\n }\r\n .brand-logo {\r\n width: clamp(40px, 8vw, 52px);\r\n height: clamp(40px, 8vw, 52px);\r\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\r\n color: white;\r\n border-radius: 14px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin: 0 auto clamp(8px, 1.5vw, 12px);\r\n box-shadow: 0 0 24px var(--app-glow, rgba(99,102,241,0.4));\r\n animation: float 4s ease-in-out infinite;\r\n }\r\n .brand-logo svg {\r\n width: clamp(20px, 4vw, 26px);\r\n height: clamp(20px, 4vw, 26px);\r\n fill: none;\r\n stroke: currentColor;\r\n stroke-width: 2;\r\n stroke-linecap: round;\r\n stroke-linejoin: round;\r\n }\r\n .brand h1 {\r\n font-size: clamp(1.2rem, 3vw, 1.65rem);\r\n font-weight: 800;\r\n margin-bottom: 3px;\r\n color: #f1f5f9;\r\n letter-spacing: -0.02em;\r\n }\r\n .brand p {\r\n color: #94a3b8;\r\n font-size: clamp(0.75rem, 1.8vw, 0.82rem);\r\n }\r\n\r\n /* ─────────────────────────────────────────\r\n EXTRA-SMALL SCREENS (< 360 px)\r\n Reduce border-radius and disable blur for\r\n performance on very low-end devices.\r\n ───────────────────────────────────────── */\r\n @media (max-width: 359px) {\r\n .auth-card {\r\n border-radius: 12px;\r\n backdrop-filter: none;\r\n -webkit-backdrop-filter: none;\r\n background: rgba(15, 20, 40, 0.97);\r\n }\r\n }\r\n\r\n /* ─────────────────────────────────────────\r\n ANIMATIONS\r\n ───────────────────────────────────────── */\r\n @keyframes fadeInUp {\r\n from { opacity: 0; transform: translateY(24px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n }\r\n @keyframes float {\r\n 0%, 100% { transform: translateY(0px); }\r\n 50% { transform: translateY(-6px); }\r\n }\r\n @keyframes blobMove1 {\r\n 0%, 100% { transform: translate(0, 0) scale(1); }\r\n 33% { transform: translate(30px, -40px) scale(1.05); }\r\n 66% { transform: translate(-20px, 20px) scale(0.95); }\r\n }\r\n @keyframes blobMove2 {\r\n 0%, 100% { transform: translate(0, 0) scale(1); }\r\n 33% { transform: translate(-30px, 30px) scale(1.05); }\r\n 66% { transform: translate(20px, -20px) scale(0.95); }\r\n }\r\n @keyframes blobMove3 {\r\n 0%, 100% { transform: translate(-50%, -50%) scale(1); }\r\n 50% { transform: translate(-50%, -50%) scale(1.2); }\r\n }\r\n\r\n /* ── Reduce motion for accessibility ── */\r\n @media (prefers-reduced-motion: reduce) {\r\n .orb, .brand-logo, .auth-card {\r\n animation: none !important;\r\n }\r\n }\r\n `]\r\n})\r\nexport class AmfAuthShellComponent {\r\n /** App brand name shown in the card header */\r\n @Input() brandName?: string;\r\n /** Tagline shown below the brand name */\r\n @Input() brandTagline?: string;\r\n /** Override the card's max-width (default 560px) */\r\n @Input() maxWidth?: string = '560px';\r\n}\r\n"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;AAoBG;MA+OU,qBAAqB,CAAA;;AAEvB,IAAA,SAAS;;AAET,IAAA,YAAY;;IAEZ,QAAQ,GAAY,OAAO;wGANzB,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAArB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,SAAA,EAAA,WAAA,EAAA,YAAA,EAAA,cAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAvOtB,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,6kHAAA,CAAA,EAAA,CAAA;;4FA2MU,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBA3OjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,UAAA,EACd,IAAI,EAAA,OAAA,EACP,EAAE,EAAA,QAAA,EACD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,6kHAAA,CAAA,EAAA;;sBA6MA;;sBAEA;;sBAEA;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs","sources":["../../../projects/avora-meta-forge/src/lib/avora-meta-forge/pages/auth/contact-support.page.ts"],"sourcesContent":["/**\r\n * Contact Support Component\r\n *\r\n * A full-page, bookmarkable /contact-support route built with AmfAuthShellComponent.\r\n * Displays three contact channel cards:\r\n * - Email Support (mailto)\r\n * - Live Chat (extensible — can wire to any chat provider)\r\n * - Documentation (external URL)\r\n *\r\n * Optionally allows submitting a support ticket with a message, powered by\r\n * the mock-contact-support endpoint (replace with real endpoint in production).\r\n */\r\nimport { Component, inject, signal } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { RouterModule } from '@angular/router';\r\n\r\nimport { ActionDispatcherService } from '../../core/action-dispatcher.service';\r\nimport { AmfAuthShellComponent } from '../../renderers/auth/amf-auth-shell.component';\r\nimport { FormRendererComponent } from '../../renderers/form/form-renderer.component';\r\nimport { FormMeta } from '../../models/meta.types';\r\nimport { APP_META_CONFIG_TOKEN } from '../../avora-meta-forge.provider';\r\ninterface ContactChannel {\r\n id: string;\r\n icon: string;\r\n gradient: string;\r\n title: string;\r\n subtitle: string;\r\n badge?: string;\r\n action: () => void;\r\n}\r\n\r\n@Component({\r\n selector: 'amf-contact-support',\r\n standalone: true,\r\n imports: [FormsModule, RouterModule, AmfAuthShellComponent, FormRendererComponent],\r\n template: `\r\n <amf-auth-shell \r\n [brandName]=\"meta.auth?.builtInUI?.brandName || meta.app.name\"\r\n [brandTagline]=\"meta.auth?.builtInUI?.brandTagline || 'We\\\\'re here to help'\" \r\n maxWidth=\"660px\">\r\n <!-- Compact header: icon inline with title -->\r\n <div class=\"cs-header\">\r\n <span class=\"ms icon-ms\">support_agent</span>\r\n <div class=\"cs-header-text\">\r\n <h2>Contact Support</h2>\r\n <p>Choose the fastest way to reach us. We typically respond within 2 hours.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Contact Channel Cards — inline 3-col grid -->\r\n <div class=\"channels\">\r\n @for (channel of channels; track channel.id) {\r\n <button\r\n class=\"channel-card\"\r\n [id]=\"'cs-' + channel.id\"\r\n (click)=\"channel.action()\"\r\n [class.active]=\"activeChannel === channel.id\"\r\n >\r\n <div class=\"channel-icon\" [style.background]=\"channel.gradient\">\r\n <span class=\"ms channel-icon-ms\">{{ channel.icon }}</span>\r\n </div>\r\n <div class=\"channel-title\">{{ channel.title }}</div>\r\n @if (channel.badge) {\r\n <span class=\"badge\">{{ channel.badge }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Quick Message Form -->\r\n <div class=\"quick-msg\">\r\n <div class=\"divider\"><span>or send a quick message</span></div>\r\n\r\n <!-- Form + actions unified container -->\r\n <div class=\"cs-form-body\">\r\n <div class=\"msg-form-container\">\r\n <amf-form-renderer \r\n [config]=\"supportForm\" \r\n (formSubmit)=\"onFormSubmit($event)\"\r\n (formChange)=\"onFormChange($event)\">\r\n </amf-form-renderer>\r\n </div>\r\n\r\n @if (successTicket()) {\r\n <div class=\"success-banner\">\r\n <span class=\"ms\" style=\"font-size:1.1rem;vertical-align:middle;margin-right:6px\">check_circle</span>\r\n Ticket <strong>{{ ticketId() }}</strong> created! We'll get back to you shortly.\r\n </div>\r\n }\r\n \r\n <div class=\"action-row\">\r\n <button type=\"button\" class=\"auth-btn\" (click)=\"triggerSubmit()\" [disabled]=\"loading() || !ticketEmail || !ticketMessage || successTicket()\">\r\n @if (loading()) {\r\n <div class=\"loader\"></div>\r\n } @else {\r\n <span>Send Message</span>\r\n <svg class=\"btn-icon\" viewBox=\"0 0 24 24\"><path d=\"M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z\"/></svg>\r\n }\r\n </button>\r\n <a routerLink=\"/login\" class=\"back-link-inline\">\r\n &larr; Back to Sign In\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n </amf-auth-shell>\r\n `,\r\n styles: [`\r\n :host { display: block; height: 100%; }\r\n\r\n /* ── Header — compact inline row ── */\r\n .cs-header {\r\n display: flex;\r\n align-items: center;\r\n gap: 14px;\r\n margin-bottom: clamp(12px, 2.5vw, 20px);\r\n padding-bottom: clamp(10px, 2vw, 16px);\r\n border-bottom: 1px solid rgba(255,255,255,0.07);\r\n }\r\n .icon-ms {\r\n font-size: 2.4rem !important;\r\n font-variation-settings: 'FILL' 1, 'wght' 300, 'GRAD' 0, 'opsz' 48;\r\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\r\n -webkit-background-clip: text;\r\n -webkit-text-fill-color: transparent;\r\n background-clip: text;\r\n flex-shrink: 0;\r\n }\r\n .cs-header-text { flex: 1; }\r\n .cs-header h2 {\r\n font-size: clamp(1.1rem, 3vw, 1.35rem);\r\n font-weight: 700;\r\n color: #f1f5f9;\r\n margin: 0 0 3px;\r\n }\r\n .cs-header p {\r\n font-size: clamp(0.75rem, 1.8vw, 0.82rem);\r\n color: #64748b;\r\n margin: 0;\r\n line-height: 1.4;\r\n }\r\n\r\n /* ── Channel Cards — inline 3-col grid ── */\r\n .channels {\r\n display: grid;\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 10px;\r\n margin-bottom: clamp(12px, 2.5vw, 20px);\r\n }\r\n\r\n .channel-card {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 6px;\r\n padding: clamp(8px, 1.5vw, 10px) 4px;\r\n background: rgba(255,255,255,0.04);\r\n border: 1px solid rgba(255,255,255,0.07);\r\n border-radius: 14px;\r\n cursor: pointer;\r\n transition: all 0.25s cubic-bezier(0.4,0,0.2,1);\r\n text-align: center;\r\n width: 100%;\r\n position: relative;\r\n overflow: hidden;\r\n }\r\n .channel-card::before {\r\n content: '';\r\n position: absolute;\r\n inset: 0;\r\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\r\n opacity: 0;\r\n transition: opacity 0.25s;\r\n }\r\n .channel-card:hover {\r\n border-color: rgba(99,102,241,0.35);\r\n background: rgba(99,102,241,0.06);\r\n transform: translateY(-3px);\r\n box-shadow: 0 6px 24px rgba(99,102,241,0.18);\r\n }\r\n .channel-card:hover::before { opacity: 0.04; }\r\n .channel-card.active {\r\n border-color: rgba(99,102,241,0.5);\r\n background: rgba(99,102,241,0.1);\r\n }\r\n\r\n .channel-icon {\r\n width: clamp(28px, 6vw, 34px);\r\n height: clamp(28px, 6vw, 34px);\r\n border-radius: 10px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n .channel-icon-ms {\r\n font-size: 1.15rem !important;\r\n font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;\r\n color: white;\r\n }\r\n .channel-title {\r\n font-size: clamp(0.7rem, 1.5vw, 0.78rem);\r\n font-weight: 600;\r\n color: #e2e8f0;\r\n position: relative;\r\n z-index: 1;\r\n line-height: 1.2;\r\n }\r\n .badge {\r\n font-size: 0.55rem;\r\n font-weight: 700;\r\n background: linear-gradient(135deg, #10b981, #059669);\r\n color: white;\r\n padding: 1px 5px;\r\n border-radius: 6px;\r\n letter-spacing: 0.03em;\r\n text-transform: uppercase;\r\n position: relative;\r\n z-index: 1;\r\n white-space: nowrap;\r\n }\r\n\r\n /* ── Quick Message ── */\r\n .quick-msg { margin-top: 0; }\r\n .divider {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-bottom: 12px;\r\n color: #475569;\r\n font-size: 0.78rem;\r\n }\r\n .divider::before, .divider::after {\r\n content: '';\r\n flex: 1;\r\n height: 1px;\r\n background: rgba(255,255,255,0.07);\r\n }\r\n\r\n /* Unified form + actions container — mirrors .auth-form-container in forgot-password */\r\n .cs-form-body { display: flex; flex-direction: column; gap: clamp(10px, 2vw, 14px); }\r\n\r\n /* Two-field inline row for wider layout */\r\n .msg-form-container { display: flex; flex-direction: column; gap: 10px; }\r\n \r\n ::ng-deep .msg-form-container .amf-form { gap: 16px; }\r\n ::ng-deep .msg-form-container .amf-form-fields { gap: 16px; align-items: stretch; }\r\n ::ng-deep .msg-form-container .amf-field { display: flex; flex-direction: column; gap: 5px; }\r\n ::ng-deep .msg-form-container .field-label {\r\n font-size: 0.8rem !important;\r\n font-weight: 600 !important;\r\n color: #94a3b8 !important;\r\n margin-bottom: 0 !important;\r\n }\r\n ::ng-deep .msg-form-container .field-input-wrapper {\r\n border-radius: 12px !important;\r\n border: 1px solid rgba(255,255,255,0.08) !important;\r\n background: rgba(255,255,255,0.04) !important;\r\n transition: all 0.25s !important;\r\n overflow: hidden;\r\n box-shadow: none !important;\r\n flex: 1;\r\n display: flex;\r\n }\r\n ::ng-deep .msg-form-container .field-input-wrapper:focus-within {\r\n border-color: var(--app-primary, #6366f1) !important;\r\n background: rgba(255,255,255,0.06) !important;\r\n box-shadow: 0 0 20px var(--app-glow, rgba(99,102,241,0.3)) !important;\r\n }\r\n ::ng-deep .msg-form-container .field-input {\r\n flex: 1;\r\n min-width: 0;\r\n padding: 12px 12px !important;\r\n border: none !important;\r\n background: transparent !important;\r\n font-size: clamp(0.875rem, 2vw, 0.9375rem) !important;\r\n color: #f1f5f9 !important;\r\n resize: none !important;\r\n font-family: inherit !important;\r\n width: 100% !important;\r\n height: 100% !important;\r\n }\r\n ::ng-deep .msg-form-container .field-input::placeholder { color: #64748b !important; }\r\n\r\n /* ── Button ── */\r\n .auth-btn {\r\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\r\n color: white;\r\n padding: clamp(11px, 2.5vw, 13px);\r\n border: none;\r\n border-radius: 12px;\r\n font-size: clamp(0.875rem, 2vw, 0.9375rem);\r\n font-weight: 600;\r\n cursor: pointer;\r\n transition: all 0.3s cubic-bezier(0.4,0,0.2,1);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n }\r\n .auth-btn:hover:not(:disabled) {\r\n transform: translateY(-2px);\r\n box-shadow: 0 10px 30px -5px var(--app-glow, rgba(99,102,241,0.5));\r\n }\r\n .auth-btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }\r\n .btn-icon {\r\n width: 15px; height: 15px;\r\n fill: none; stroke: currentColor; stroke-width: 2.5;\r\n stroke-linecap: round; stroke-linejoin: round;\r\n flex-shrink: 0;\r\n }\r\n\r\n /* ── Success Banner ── */\r\n .success-banner {\r\n background: rgba(16,185,129,0.1);\r\n border: 1px solid rgba(16,185,129,0.3);\r\n border-radius: 12px;\r\n padding: 14px 16px;\r\n font-size: 0.875rem;\r\n color: #6ee7b7;\r\n text-align: center;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n }\r\n\r\n /* ── Action Row ── */\r\n .action-row {\r\n display: flex;\r\n gap: 10px;\r\n margin-top: 0; /* spacing handled by .cs-form-body gap */\r\n }\r\n .action-row > * {\r\n flex: 1;\r\n }\r\n .back-link-inline {\r\n padding: clamp(12px, 2.5vw, 15px) 16px;\r\n border-radius: 12px;\r\n font-size: clamp(0.875rem, 2vw, 0.9375rem);\r\n font-weight: 600;\r\n transition: all 0.3s cubic-bezier(0.4,0,0.2,1);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n text-decoration: none;\r\n background: rgba(255,255,255,0.04);\r\n color: #94a3b8;\r\n border: 1px solid rgba(255,255,255,0.1);\r\n }\r\n .back-link-inline:hover {\r\n background: rgba(255,255,255,0.08);\r\n color: white;\r\n }\r\n .loader {\r\n width: 18px; height: 18px;\r\n border: 2.5px solid rgba(255,255,255,0.2);\r\n border-top-color: white;\r\n border-radius: 50%;\r\n animation: spin 0.8s linear infinite;\r\n }\r\n @keyframes spin { to { transform: rotate(360deg); } }\r\n @keyframes float {\r\n 0%, 100% { transform: translateY(0); }\r\n 50% { transform: translateY(-6px); }\r\n }\r\n\r\n /* ── Responsive: stack 3-col to single col on small screens ── */\r\n @media (max-width: 400px) {\r\n .channels { grid-template-columns: 1fr; }\r\n .channel-card { flex-direction: row; text-align: left; gap: 10px; }\r\n /* Kept .form-row as 2 columns per user request */\r\n }\r\n @media (max-width: 500px) {\r\n .cs-header { flex-direction: column; text-align: center; gap: 8px; }\r\n .cs-header-text { text-align: center; }\r\n }\r\n @media (prefers-reduced-motion: reduce) {\r\n .icon-wrap, .channel-card { animation: none !important; }\r\n }\r\n `]\r\n})\r\nexport class ContactSupportComponent {\r\n private readonly dispatcher = inject(ActionDispatcherService);\r\n protected meta: any = inject(APP_META_CONFIG_TOKEN, { optional: true }) || { app: { name: 'AvoraMetaForge' } };\r\n\r\n loading = signal(false);\r\n successTicket = signal(false);\r\n ticketId = signal('');\r\n activeChannel = '';\r\n\r\n ticketEmail = '';\r\n ticketMessage = '';\r\n\r\n supportForm: FormMeta = {\r\n id: 'supportForm',\r\n layout: 'vertical',\r\n hideSubmit: true,\r\n fields: [\r\n {\r\n key: 'email',\r\n type: 'email',\r\n label: 'Your Email',\r\n placeholder: 'name@company.com',\r\n validators: [{ type: 'required' }]\r\n },\r\n {\r\n key: 'message',\r\n type: 'textarea',\r\n label: 'How can we help?',\r\n placeholder: 'Describe your issue...',\r\n rows: 3,\r\n validators: [{ type: 'required' }]\r\n }\r\n ]\r\n };\r\n\r\n readonly channels: ContactChannel[] = [\r\n {\r\n id: 'email',\r\n icon: 'mail',\r\n gradient: 'linear-gradient(135deg, rgba(59,130,246,0.3), rgba(99,102,241,0.3))',\r\n title: 'Email Support',\r\n subtitle: 'Detailed help via email • Avg. 2h response',\r\n badge: 'Recommended',\r\n action: () => {\r\n this.activeChannel = 'email';\r\n // DEMO: opens mailto link. REAL: can open a support ticket form or redirect to helpdesk.\r\n this.dispatcher.dispatch({\r\n type: 'open-url',\r\n config: { url: 'mailto:support@avorametaforge.com?subject=Support Request', target: '_self' }\r\n });\r\n }\r\n },\r\n {\r\n id: 'chat',\r\n icon: 'chat_bubble',\r\n gradient: 'linear-gradient(135deg, rgba(16,185,129,0.3), rgba(5,150,105,0.3))',\r\n title: 'Live Chat',\r\n subtitle: 'Real-time help with our team • Now available',\r\n action: () => {\r\n this.activeChannel = 'chat';\r\n // DEMO: shows a notification. REAL: wire to Intercom, Crisp, Zendesk, etc.\r\n this.dispatcher.dispatch({\r\n type: 'notify',\r\n config: { type: 'info', message: 'Live chat integration is configurable. Wire to Intercom, Crisp, or any provider.' }\r\n });\r\n }\r\n },\r\n {\r\n id: 'docs',\r\n icon: 'menu_book',\r\n gradient: 'linear-gradient(135deg, rgba(245,158,11,0.3), rgba(217,119,6,0.3))',\r\n title: 'Documentation',\r\n subtitle: 'Browse guides, API reference & tutorials',\r\n action: () => {\r\n this.activeChannel = 'docs';\r\n this.dispatcher.dispatch({\r\n type: 'open-url',\r\n config: { url: 'https://github.com/AvoraLabs/avora-meta-forge', target: '_blank' }\r\n });\r\n }\r\n }\r\n ];\r\n\r\n onFormChange(values: any): void {\r\n this.ticketEmail = values.email || '';\r\n this.ticketMessage = values.message || '';\r\n }\r\n\r\n triggerSubmit(): void {\r\n this.dispatcher.dispatch({ type: 'submit-form', config: { formId: 'supportForm' } });\r\n }\r\n\r\n onFormSubmit(values: any): void {\r\n if (!values.email || !values.message) return;\r\n\r\n this.loading.set(true);\r\n\r\n // DEMO: calls mock-contact-support endpoint.\r\n // REAL: remove mock:true from 'mock-contact-support' and point to your helpdesk API.\r\n this.dispatcher.dispatch({\r\n type: 'api',\r\n config: {\r\n endpointId: 'mock-contact-support',\r\n body: { email: values.email, message: values.message },\r\n storeResultAs: 'supportResult'\r\n },\r\n then: {\r\n type: 'notify',\r\n config: { type: 'success', message: 'Your message has been sent! We\\'ll respond to ' + values.email }\r\n },\r\n onError: {\r\n type: 'notify',\r\n config: { type: 'error', message: 'Failed to send. Please try emailing us directly.' }\r\n }\r\n }).then((result: any) => {\r\n if (result?.ticketId) {\r\n this.ticketId.set(result.ticketId);\r\n this.successTicket.set(true);\r\n }\r\n }).finally(() => this.loading.set(false));\r\n }\r\n}\r\n"],"names":[],"mappings":"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"}