@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
@@ -4,7 +4,7 @@ import { FormsModule } from '@angular/forms';
4
4
  import * as i1 from '@angular/router';
5
5
  import { Router, RouterModule } from '@angular/router';
6
6
  import { ActionDispatcherService, MetaStateService, APP_META_CONFIG_TOKEN, FormRendererComponent } from './avora-labs-meta-forge.mjs';
7
- import { A as AmfAuthShellComponent } from './avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs';
7
+ import { A as AmfAuthShellComponent } from './avora-labs-meta-forge-amf-auth-shell.component-FCubZyZ1.mjs';
8
8
 
9
9
  /**
10
10
  * Forgot Password Component
@@ -220,248 +220,248 @@ class ForgotPasswordComponent {
220
220
  }).finally(() => this.loading.set(false));
221
221
  }
222
222
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ForgotPasswordComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
223
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: ForgotPasswordComponent, isStandalone: true, selector: "amf-forgot-password", ngImport: i0, template: `
224
- <amf-auth-shell
225
- [brandName]="meta.auth?.builtInUI?.brandName || meta.app.name"
226
- [brandTagline]="meta.auth?.builtInUI?.brandTagline || 'Recover your account'"
227
- maxWidth="620px">
228
- <!-- Step Indicator -->
229
- <div class="steps">
230
- <div class="step" [class.active]="currentStep() === 'email'" [class.done]="currentStep() === 'reset'">
231
- <div class="step-dot">
232
- @if (currentStep() === 'reset') {
233
- <span class="ms step-icon">check</span>
234
- } @else {
235
- <span>1</span>
236
- }
237
- </div>
238
- <span class="step-label">Email</span>
239
- </div>
240
- <div class="step-line" [class.done]="currentStep() === 'reset'"></div>
241
- <div class="step" [class.active]="currentStep() === 'reset'">
242
- <div class="step-dot"><span>2</span></div>
243
- <span class="step-label">New Password</span>
244
- </div>
245
- </div>
246
-
247
- <!-- ── STEP 1: Email ── -->
248
- @if (currentStep() === 'email') {
249
- <div class="form-section">
250
- <div class="screen-label">
251
- <div class="icon-wrap"><span class="ms icon-ms">lock</span></div>
252
- <h2>Forgot your password?</h2>
253
- <p>Enter your email and we'll send a verification code.</p>
254
- </div>
255
-
256
- <div class="auth-form-container">
257
- <amf-form-renderer
258
- [config]="emailForm"
259
- (formSubmit)="onEmailSubmit($event)"
260
- (formChange)="onEmailChange($event)">
261
- </amf-form-renderer>
262
-
263
- @if (errorMsg()) {
264
- <div class="error-banner">{{ errorMsg() }}</div>
265
- }
266
-
267
- <div class="action-row">
268
- <button type="button" class="auth-btn" (click)="triggerEmailSubmit()" [disabled]="loading() || !email">
269
- @if (loading()) {
270
- <div class="loader"></div>
271
- } @else {
272
- <span>Send Verification Code</span>
273
- }
274
- </button>
275
- <a routerLink="/login" class="back-link-inline">
276
- <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
277
- Back to Sign In
278
- </a>
279
- </div>
280
- </div>
281
- </div>
282
- }
283
-
284
- <!-- ── STEP 2: New Password (after OTP verified) ── -->
285
- @if (currentStep() === 'reset') {
286
- <div class="form-section">
287
- <!-- Compact inline header for step 2 -->
288
- <div class="screen-label screen-label-sm">
289
- <span class="ms icon-ms icon-ms-inline">key</span>
290
- <div>
291
- <h2>Set a new password</h2>
292
- <p>Identity verified — choose a strong password.</p>
293
- </div>
294
- </div>
295
-
296
- <div class="auth-form-container">
297
- <amf-form-renderer
298
- [config]="resetForm"
299
- (formSubmit)="onResetSubmit($event)"
300
- (formChange)="onResetChange($event)">
301
- </amf-form-renderer>
302
-
303
- @if (confirmError) {
304
- <span class="field-error" style="margin-top: -10px; display: block;">Passwords don't match</span>
305
- }
306
-
307
- <!-- Strength bar: only show once user starts typing -->
308
- @if (newPassword) {
309
- <div class="strength-bar">
310
- <div class="strength-track">
311
- <div class="strength-fill" [style.width]="strengthPct + '%'" [class]="'strength-' + strengthLevel"></div>
312
- </div>
313
- <span class="strength-label">{{ strengthLabel }}</span>
314
- </div>
315
- }
316
-
317
- @if (errorMsg()) {
318
- <div class="error-banner">{{ errorMsg() }}</div>
319
- }
320
-
321
- <!-- Inline action row: equal-width Submit + Back -->
322
- <div class="action-row">
323
- <button type="button" class="auth-btn" (click)="triggerResetSubmit()" [disabled]="loading() || !newPassword || !confirmPassword || confirmError">
324
- @if (loading()) {
325
- <div class="loader"></div>
326
- } @else {
327
- <span>Update Password</span>
328
- }
329
- </button>
330
- <a routerLink="/login" class="back-link-inline">
331
- <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
332
- Back to Sign In
333
- </a>
334
- </div>
335
- </div>
336
- </div>
337
- }
338
-
339
-
340
- </amf-auth-shell>
223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: ForgotPasswordComponent, isStandalone: true, selector: "amf-forgot-password", ngImport: i0, template: `
224
+ <amf-auth-shell
225
+ [brandName]="meta.auth?.builtInUI?.brandName || meta.app.name"
226
+ [brandTagline]="meta.auth?.builtInUI?.brandTagline || 'Recover your account'"
227
+ maxWidth="620px">
228
+ <!-- Step Indicator -->
229
+ <div class="steps">
230
+ <div class="step" [class.active]="currentStep() === 'email'" [class.done]="currentStep() === 'reset'">
231
+ <div class="step-dot">
232
+ @if (currentStep() === 'reset') {
233
+ <span class="ms step-icon">check</span>
234
+ } @else {
235
+ <span>1</span>
236
+ }
237
+ </div>
238
+ <span class="step-label">Email</span>
239
+ </div>
240
+ <div class="step-line" [class.done]="currentStep() === 'reset'"></div>
241
+ <div class="step" [class.active]="currentStep() === 'reset'">
242
+ <div class="step-dot"><span>2</span></div>
243
+ <span class="step-label">New Password</span>
244
+ </div>
245
+ </div>
246
+
247
+ <!-- ── STEP 1: Email ── -->
248
+ @if (currentStep() === 'email') {
249
+ <div class="form-section">
250
+ <div class="screen-label">
251
+ <div class="icon-wrap"><span class="ms icon-ms">lock</span></div>
252
+ <h2>Forgot your password?</h2>
253
+ <p>Enter your email and we'll send a verification code.</p>
254
+ </div>
255
+
256
+ <div class="auth-form-container">
257
+ <amf-form-renderer
258
+ [config]="emailForm"
259
+ (formSubmit)="onEmailSubmit($event)"
260
+ (formChange)="onEmailChange($event)">
261
+ </amf-form-renderer>
262
+
263
+ @if (errorMsg()) {
264
+ <div class="error-banner">{{ errorMsg() }}</div>
265
+ }
266
+
267
+ <div class="action-row">
268
+ <button type="button" class="auth-btn" (click)="triggerEmailSubmit()" [disabled]="loading() || !email">
269
+ @if (loading()) {
270
+ <div class="loader"></div>
271
+ } @else {
272
+ <span>Send Verification Code</span>
273
+ }
274
+ </button>
275
+ <a routerLink="/login" class="back-link-inline">
276
+ <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
277
+ Back to Sign In
278
+ </a>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ }
283
+
284
+ <!-- ── STEP 2: New Password (after OTP verified) ── -->
285
+ @if (currentStep() === 'reset') {
286
+ <div class="form-section">
287
+ <!-- Compact inline header for step 2 -->
288
+ <div class="screen-label screen-label-sm">
289
+ <span class="ms icon-ms icon-ms-inline">key</span>
290
+ <div>
291
+ <h2>Set a new password</h2>
292
+ <p>Identity verified — choose a strong password.</p>
293
+ </div>
294
+ </div>
295
+
296
+ <div class="auth-form-container">
297
+ <amf-form-renderer
298
+ [config]="resetForm"
299
+ (formSubmit)="onResetSubmit($event)"
300
+ (formChange)="onResetChange($event)">
301
+ </amf-form-renderer>
302
+
303
+ @if (confirmError) {
304
+ <span class="field-error" style="margin-top: -10px; display: block;">Passwords don't match</span>
305
+ }
306
+
307
+ <!-- Strength bar: only show once user starts typing -->
308
+ @if (newPassword) {
309
+ <div class="strength-bar">
310
+ <div class="strength-track">
311
+ <div class="strength-fill" [style.width]="strengthPct + '%'" [class]="'strength-' + strengthLevel"></div>
312
+ </div>
313
+ <span class="strength-label">{{ strengthLabel }}</span>
314
+ </div>
315
+ }
316
+
317
+ @if (errorMsg()) {
318
+ <div class="error-banner">{{ errorMsg() }}</div>
319
+ }
320
+
321
+ <!-- Inline action row: equal-width Submit + Back -->
322
+ <div class="action-row">
323
+ <button type="button" class="auth-btn" (click)="triggerResetSubmit()" [disabled]="loading() || !newPassword || !confirmPassword || confirmError">
324
+ @if (loading()) {
325
+ <div class="loader"></div>
326
+ } @else {
327
+ <span>Update Password</span>
328
+ }
329
+ </button>
330
+ <a routerLink="/login" class="back-link-inline">
331
+ <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
332
+ Back to Sign In
333
+ </a>
334
+ </div>
335
+ </div>
336
+ </div>
337
+ }
338
+
339
+
340
+ </amf-auth-shell>
341
341
  `, isInline: true, styles: [":host{display:block;height:100%}.steps{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:clamp(12px,2.5vw,20px)}.step{display:flex;flex-direction:column;align-items:center;gap:6px}.step-dot{width:32px;height:32px;border-radius:50%;border:2px solid rgba(255,255,255,.15);background:#ffffff0a;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;color:#64748b;transition:all .3s}.step.active .step-dot{border-color:var(--app-primary, #6366f1);background:#6366f126;color:var(--app-primary, #6366f1);box-shadow:0 0 16px var(--app-glow, rgba(99,102,241,.4))}.step.done .step-dot{border-color:#10b981;background:#10b98126;color:#10b981}.step-icon{font-size:1rem!important}.step-label{font-size:.7rem;color:#64748b;font-weight:600;text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}.step.active .step-label{color:#94a3b8}.step-line{flex:1;height:2px;background:#ffffff14;margin:0 8px 22px;min-width:24px;transition:background .3s}.step-line.done{background:#10b98166}.screen-label{text-align:center;margin-bottom:clamp(10px,2vw,16px)}.screen-label-sm{display:flex;align-items:center;gap:12px;text-align:left;padding:10px 14px;background:#ffffff08;border:1px solid rgba(255,255,255,.07);border-radius:12px;margin-bottom:clamp(10px,2vw,14px)}.screen-label-sm h2{font-size:clamp(1rem,3vw,1.15rem)!important;margin-bottom:2px!important}.screen-label-sm p{font-size:clamp(.75rem,1.8vw,.82rem)!important;margin:0}.icon-ms-inline{font-size:1.75rem!important;flex-shrink:0;animation:float 3s ease-in-out infinite}.icon-wrap{margin-bottom:6px;display:flex;align-items:center;justify-content:center;animation:float 3s ease-in-out infinite}.icon-ms{font-size:2.1rem!important;font-variation-settings:\"FILL\" 1,\"wght\" 300,\"GRAD\" 0,\"opsz\" 48;background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.screen-label h2{font-size:clamp(1.15rem,4vw,1.4rem);font-weight:700;color:#f1f5f9;margin-bottom:6px}.screen-label p{font-size:clamp(.8rem,2vw,.875rem);color:#64748b;line-height:1.5}.pw-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}@media(max-width:460px){.pw-row{grid-template-columns:1fr}.screen-label-sm{flex-direction:column;text-align:center}}.auth-form-container{display:flex;flex-direction:column;gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-form{gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-form-fields{gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-field{display:flex;flex-direction:column;gap:8px}::ng-deep .auth-form-container .field-label{font-size:.875rem!important;font-weight:600!important;color:#cbd5e1!important;margin-bottom:0!important}::ng-deep .auth-form-container .field-input-wrapper{border-radius:12px!important;border:1px solid rgba(255,255,255,.08)!important;background:#ffffff0a!important;transition:all .25s!important;overflow:hidden;box-shadow:none!important;display:flex;align-items:center}::ng-deep .auth-form-container .field-input-wrapper:focus-within{border-color:var(--app-primary, #6366f1)!important;background:#ffffff0f!important;box-shadow:0 0 20px var(--app-glow, rgba(99,102,241,.3))!important}::ng-deep .auth-form-container .field-input{flex:1;min-width:0;padding:13px 16px!important;border:none!important;background:transparent!important;font-size:clamp(.9rem,2vw,1rem)!important;color:#f1f5f9!important}::ng-deep .auth-form-container .field-input::placeholder{color:#64748b!important}::ng-deep .auth-form-container .pwd-toggle-btn{color:#64748b!important}::ng-deep .auth-form-container .pwd-toggle-btn:hover{color:var(--app-primary, #6366f1)!important}.field-error{font-size:.78rem;color:#ef4444}.strength-bar{display:flex;align-items:center;gap:10px}.strength-track{flex:1;height:4px;background:#ffffff12;border-radius:2px;overflow:hidden}.strength-fill{height:100%;border-radius:2px;transition:width .4s,background .4s}.strength-weak{background:#ef4444}.strength-fair{background:#f59e0b}.strength-good{background:#10b981}.strength-strong{background:#6366f1}.strength-label{font-size:.75rem;color:#64748b;white-space:nowrap}.auth-btn{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:clamp(11px,2.5vw,14px);border:none;border-radius:12px;font-size:clamp(.9rem,2vw,1rem);font-weight:600;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;align-items:center;justify-content:center;gap:8px;flex:1;min-width:0;position:relative;overflow:hidden}.auth-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 10px 30px -5px var(--app-glow, rgba(99,102,241,.5))}.auth-btn:disabled{opacity:.6;cursor:not-allowed;transform:none}.btn-icon{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}.error-banner{background:#ef44441a;border:1px solid rgba(239,68,68,.3);border-radius:10px;padding:12px 16px;font-size:.875rem;color:#fca5a5}.footer-note{text-align:center;margin-top:clamp(10px,2vw,18px)}.back-link{display:inline-flex;align-items:center;gap:6px;font-size:.875rem;color:#64748b;font-weight:500;transition:color .2s;text-decoration:none}.back-link svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}.back-link:hover{color:var(--app-primary, #6366f1)}.action-row{display:flex;align-items:stretch;gap:10px}.back-link-inline{display:flex;align-items:center;justify-content:center;gap:6px;flex:1;min-width:0;padding:clamp(11px,2.5vw,14px) 12px;border-radius:12px;border:1px solid rgba(255,255,255,.1);background:#ffffff0a;color:#94a3b8;font-size:clamp(.82rem,2vw,.9rem);font-weight:500;text-decoration:none;white-space:nowrap;transition:all .2s}.back-link-inline svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}.back-link-inline:hover{color:#f1f5f9;border-color:#6366f159;background:#6366f10f}.loader{width:20px;height:20px;border:3px solid rgba(255,255,255,.2);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@media(max-width:400px){.steps{margin-bottom:14px}.step-line{margin:0 4px 22px;min-width:12px}.step-label{font-size:.6rem}.screen-label{margin-bottom:12px}.icon-ms{font-size:2.25rem!important}.auth-form{gap:12px}}@media(prefers-reduced-motion:reduce){.icon-wrap,.loader{animation:none!important}}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: AmfAuthShellComponent, selector: "amf-auth-shell", inputs: ["brandName", "brandTagline", "maxWidth"] }, { kind: "component", type: FormRendererComponent, selector: "amf-form-renderer", inputs: ["config", "context"], outputs: ["formSubmit", "formCancel", "formChange"] }] });
342
342
  }
343
343
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: ForgotPasswordComponent, decorators: [{
344
344
  type: Component,
345
- args: [{ selector: 'amf-forgot-password', standalone: true, imports: [FormsModule, RouterModule, AmfAuthShellComponent, FormRendererComponent], template: `
346
- <amf-auth-shell
347
- [brandName]="meta.auth?.builtInUI?.brandName || meta.app.name"
348
- [brandTagline]="meta.auth?.builtInUI?.brandTagline || 'Recover your account'"
349
- maxWidth="620px">
350
- <!-- Step Indicator -->
351
- <div class="steps">
352
- <div class="step" [class.active]="currentStep() === 'email'" [class.done]="currentStep() === 'reset'">
353
- <div class="step-dot">
354
- @if (currentStep() === 'reset') {
355
- <span class="ms step-icon">check</span>
356
- } @else {
357
- <span>1</span>
358
- }
359
- </div>
360
- <span class="step-label">Email</span>
361
- </div>
362
- <div class="step-line" [class.done]="currentStep() === 'reset'"></div>
363
- <div class="step" [class.active]="currentStep() === 'reset'">
364
- <div class="step-dot"><span>2</span></div>
365
- <span class="step-label">New Password</span>
366
- </div>
367
- </div>
368
-
369
- <!-- ── STEP 1: Email ── -->
370
- @if (currentStep() === 'email') {
371
- <div class="form-section">
372
- <div class="screen-label">
373
- <div class="icon-wrap"><span class="ms icon-ms">lock</span></div>
374
- <h2>Forgot your password?</h2>
375
- <p>Enter your email and we'll send a verification code.</p>
376
- </div>
377
-
378
- <div class="auth-form-container">
379
- <amf-form-renderer
380
- [config]="emailForm"
381
- (formSubmit)="onEmailSubmit($event)"
382
- (formChange)="onEmailChange($event)">
383
- </amf-form-renderer>
384
-
385
- @if (errorMsg()) {
386
- <div class="error-banner">{{ errorMsg() }}</div>
387
- }
388
-
389
- <div class="action-row">
390
- <button type="button" class="auth-btn" (click)="triggerEmailSubmit()" [disabled]="loading() || !email">
391
- @if (loading()) {
392
- <div class="loader"></div>
393
- } @else {
394
- <span>Send Verification Code</span>
395
- }
396
- </button>
397
- <a routerLink="/login" class="back-link-inline">
398
- <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
399
- Back to Sign In
400
- </a>
401
- </div>
402
- </div>
403
- </div>
404
- }
405
-
406
- <!-- ── STEP 2: New Password (after OTP verified) ── -->
407
- @if (currentStep() === 'reset') {
408
- <div class="form-section">
409
- <!-- Compact inline header for step 2 -->
410
- <div class="screen-label screen-label-sm">
411
- <span class="ms icon-ms icon-ms-inline">key</span>
412
- <div>
413
- <h2>Set a new password</h2>
414
- <p>Identity verified — choose a strong password.</p>
415
- </div>
416
- </div>
417
-
418
- <div class="auth-form-container">
419
- <amf-form-renderer
420
- [config]="resetForm"
421
- (formSubmit)="onResetSubmit($event)"
422
- (formChange)="onResetChange($event)">
423
- </amf-form-renderer>
424
-
425
- @if (confirmError) {
426
- <span class="field-error" style="margin-top: -10px; display: block;">Passwords don't match</span>
427
- }
428
-
429
- <!-- Strength bar: only show once user starts typing -->
430
- @if (newPassword) {
431
- <div class="strength-bar">
432
- <div class="strength-track">
433
- <div class="strength-fill" [style.width]="strengthPct + '%'" [class]="'strength-' + strengthLevel"></div>
434
- </div>
435
- <span class="strength-label">{{ strengthLabel }}</span>
436
- </div>
437
- }
438
-
439
- @if (errorMsg()) {
440
- <div class="error-banner">{{ errorMsg() }}</div>
441
- }
442
-
443
- <!-- Inline action row: equal-width Submit + Back -->
444
- <div class="action-row">
445
- <button type="button" class="auth-btn" (click)="triggerResetSubmit()" [disabled]="loading() || !newPassword || !confirmPassword || confirmError">
446
- @if (loading()) {
447
- <div class="loader"></div>
448
- } @else {
449
- <span>Update Password</span>
450
- }
451
- </button>
452
- <a routerLink="/login" class="back-link-inline">
453
- <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
454
- Back to Sign In
455
- </a>
456
- </div>
457
- </div>
458
- </div>
459
- }
460
-
461
-
462
- </amf-auth-shell>
345
+ args: [{ selector: 'amf-forgot-password', standalone: true, imports: [FormsModule, RouterModule, AmfAuthShellComponent, FormRendererComponent], template: `
346
+ <amf-auth-shell
347
+ [brandName]="meta.auth?.builtInUI?.brandName || meta.app.name"
348
+ [brandTagline]="meta.auth?.builtInUI?.brandTagline || 'Recover your account'"
349
+ maxWidth="620px">
350
+ <!-- Step Indicator -->
351
+ <div class="steps">
352
+ <div class="step" [class.active]="currentStep() === 'email'" [class.done]="currentStep() === 'reset'">
353
+ <div class="step-dot">
354
+ @if (currentStep() === 'reset') {
355
+ <span class="ms step-icon">check</span>
356
+ } @else {
357
+ <span>1</span>
358
+ }
359
+ </div>
360
+ <span class="step-label">Email</span>
361
+ </div>
362
+ <div class="step-line" [class.done]="currentStep() === 'reset'"></div>
363
+ <div class="step" [class.active]="currentStep() === 'reset'">
364
+ <div class="step-dot"><span>2</span></div>
365
+ <span class="step-label">New Password</span>
366
+ </div>
367
+ </div>
368
+
369
+ <!-- ── STEP 1: Email ── -->
370
+ @if (currentStep() === 'email') {
371
+ <div class="form-section">
372
+ <div class="screen-label">
373
+ <div class="icon-wrap"><span class="ms icon-ms">lock</span></div>
374
+ <h2>Forgot your password?</h2>
375
+ <p>Enter your email and we'll send a verification code.</p>
376
+ </div>
377
+
378
+ <div class="auth-form-container">
379
+ <amf-form-renderer
380
+ [config]="emailForm"
381
+ (formSubmit)="onEmailSubmit($event)"
382
+ (formChange)="onEmailChange($event)">
383
+ </amf-form-renderer>
384
+
385
+ @if (errorMsg()) {
386
+ <div class="error-banner">{{ errorMsg() }}</div>
387
+ }
388
+
389
+ <div class="action-row">
390
+ <button type="button" class="auth-btn" (click)="triggerEmailSubmit()" [disabled]="loading() || !email">
391
+ @if (loading()) {
392
+ <div class="loader"></div>
393
+ } @else {
394
+ <span>Send Verification Code</span>
395
+ }
396
+ </button>
397
+ <a routerLink="/login" class="back-link-inline">
398
+ <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
399
+ Back to Sign In
400
+ </a>
401
+ </div>
402
+ </div>
403
+ </div>
404
+ }
405
+
406
+ <!-- ── STEP 2: New Password (after OTP verified) ── -->
407
+ @if (currentStep() === 'reset') {
408
+ <div class="form-section">
409
+ <!-- Compact inline header for step 2 -->
410
+ <div class="screen-label screen-label-sm">
411
+ <span class="ms icon-ms icon-ms-inline">key</span>
412
+ <div>
413
+ <h2>Set a new password</h2>
414
+ <p>Identity verified — choose a strong password.</p>
415
+ </div>
416
+ </div>
417
+
418
+ <div class="auth-form-container">
419
+ <amf-form-renderer
420
+ [config]="resetForm"
421
+ (formSubmit)="onResetSubmit($event)"
422
+ (formChange)="onResetChange($event)">
423
+ </amf-form-renderer>
424
+
425
+ @if (confirmError) {
426
+ <span class="field-error" style="margin-top: -10px; display: block;">Passwords don't match</span>
427
+ }
428
+
429
+ <!-- Strength bar: only show once user starts typing -->
430
+ @if (newPassword) {
431
+ <div class="strength-bar">
432
+ <div class="strength-track">
433
+ <div class="strength-fill" [style.width]="strengthPct + '%'" [class]="'strength-' + strengthLevel"></div>
434
+ </div>
435
+ <span class="strength-label">{{ strengthLabel }}</span>
436
+ </div>
437
+ }
438
+
439
+ @if (errorMsg()) {
440
+ <div class="error-banner">{{ errorMsg() }}</div>
441
+ }
442
+
443
+ <!-- Inline action row: equal-width Submit + Back -->
444
+ <div class="action-row">
445
+ <button type="button" class="auth-btn" (click)="triggerResetSubmit()" [disabled]="loading() || !newPassword || !confirmPassword || confirmError">
446
+ @if (loading()) {
447
+ <div class="loader"></div>
448
+ } @else {
449
+ <span>Update Password</span>
450
+ }
451
+ </button>
452
+ <a routerLink="/login" class="back-link-inline">
453
+ <svg viewBox="0 0 24 24"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
454
+ Back to Sign In
455
+ </a>
456
+ </div>
457
+ </div>
458
+ </div>
459
+ }
460
+
461
+
462
+ </amf-auth-shell>
463
463
  `, styles: [":host{display:block;height:100%}.steps{display:flex;align-items:center;justify-content:center;gap:0;margin-bottom:clamp(12px,2.5vw,20px)}.step{display:flex;flex-direction:column;align-items:center;gap:6px}.step-dot{width:32px;height:32px;border-radius:50%;border:2px solid rgba(255,255,255,.15);background:#ffffff0a;display:flex;align-items:center;justify-content:center;font-size:.75rem;font-weight:700;color:#64748b;transition:all .3s}.step.active .step-dot{border-color:var(--app-primary, #6366f1);background:#6366f126;color:var(--app-primary, #6366f1);box-shadow:0 0 16px var(--app-glow, rgba(99,102,241,.4))}.step.done .step-dot{border-color:#10b981;background:#10b98126;color:#10b981}.step-icon{font-size:1rem!important}.step-label{font-size:.7rem;color:#64748b;font-weight:600;text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}.step.active .step-label{color:#94a3b8}.step-line{flex:1;height:2px;background:#ffffff14;margin:0 8px 22px;min-width:24px;transition:background .3s}.step-line.done{background:#10b98166}.screen-label{text-align:center;margin-bottom:clamp(10px,2vw,16px)}.screen-label-sm{display:flex;align-items:center;gap:12px;text-align:left;padding:10px 14px;background:#ffffff08;border:1px solid rgba(255,255,255,.07);border-radius:12px;margin-bottom:clamp(10px,2vw,14px)}.screen-label-sm h2{font-size:clamp(1rem,3vw,1.15rem)!important;margin-bottom:2px!important}.screen-label-sm p{font-size:clamp(.75rem,1.8vw,.82rem)!important;margin:0}.icon-ms-inline{font-size:1.75rem!important;flex-shrink:0;animation:float 3s ease-in-out infinite}.icon-wrap{margin-bottom:6px;display:flex;align-items:center;justify-content:center;animation:float 3s ease-in-out infinite}.icon-ms{font-size:2.1rem!important;font-variation-settings:\"FILL\" 1,\"wght\" 300,\"GRAD\" 0,\"opsz\" 48;background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.screen-label h2{font-size:clamp(1.15rem,4vw,1.4rem);font-weight:700;color:#f1f5f9;margin-bottom:6px}.screen-label p{font-size:clamp(.8rem,2vw,.875rem);color:#64748b;line-height:1.5}.pw-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}@media(max-width:460px){.pw-row{grid-template-columns:1fr}.screen-label-sm{flex-direction:column;text-align:center}}.auth-form-container{display:flex;flex-direction:column;gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-form{gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-form-fields{gap:clamp(10px,2vw,14px)}::ng-deep .auth-form-container .amf-field{display:flex;flex-direction:column;gap:8px}::ng-deep .auth-form-container .field-label{font-size:.875rem!important;font-weight:600!important;color:#cbd5e1!important;margin-bottom:0!important}::ng-deep .auth-form-container .field-input-wrapper{border-radius:12px!important;border:1px solid rgba(255,255,255,.08)!important;background:#ffffff0a!important;transition:all .25s!important;overflow:hidden;box-shadow:none!important;display:flex;align-items:center}::ng-deep .auth-form-container .field-input-wrapper:focus-within{border-color:var(--app-primary, #6366f1)!important;background:#ffffff0f!important;box-shadow:0 0 20px var(--app-glow, rgba(99,102,241,.3))!important}::ng-deep .auth-form-container .field-input{flex:1;min-width:0;padding:13px 16px!important;border:none!important;background:transparent!important;font-size:clamp(.9rem,2vw,1rem)!important;color:#f1f5f9!important}::ng-deep .auth-form-container .field-input::placeholder{color:#64748b!important}::ng-deep .auth-form-container .pwd-toggle-btn{color:#64748b!important}::ng-deep .auth-form-container .pwd-toggle-btn:hover{color:var(--app-primary, #6366f1)!important}.field-error{font-size:.78rem;color:#ef4444}.strength-bar{display:flex;align-items:center;gap:10px}.strength-track{flex:1;height:4px;background:#ffffff12;border-radius:2px;overflow:hidden}.strength-fill{height:100%;border-radius:2px;transition:width .4s,background .4s}.strength-weak{background:#ef4444}.strength-fair{background:#f59e0b}.strength-good{background:#10b981}.strength-strong{background:#6366f1}.strength-label{font-size:.75rem;color:#64748b;white-space:nowrap}.auth-btn{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:clamp(11px,2.5vw,14px);border:none;border-radius:12px;font-size:clamp(.9rem,2vw,1rem);font-weight:600;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);display:flex;align-items:center;justify-content:center;gap:8px;flex:1;min-width:0;position:relative;overflow:hidden}.auth-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 10px 30px -5px var(--app-glow, rgba(99,102,241,.5))}.auth-btn:disabled{opacity:.6;cursor:not-allowed;transform:none}.btn-icon{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}.error-banner{background:#ef44441a;border:1px solid rgba(239,68,68,.3);border-radius:10px;padding:12px 16px;font-size:.875rem;color:#fca5a5}.footer-note{text-align:center;margin-top:clamp(10px,2vw,18px)}.back-link{display:inline-flex;align-items:center;gap:6px;font-size:.875rem;color:#64748b;font-weight:500;transition:color .2s;text-decoration:none}.back-link svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}.back-link:hover{color:var(--app-primary, #6366f1)}.action-row{display:flex;align-items:stretch;gap:10px}.back-link-inline{display:flex;align-items:center;justify-content:center;gap:6px;flex:1;min-width:0;padding:clamp(11px,2.5vw,14px) 12px;border-radius:12px;border:1px solid rgba(255,255,255,.1);background:#ffffff0a;color:#94a3b8;font-size:clamp(.82rem,2vw,.9rem);font-weight:500;text-decoration:none;white-space:nowrap;transition:all .2s}.back-link-inline svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}.back-link-inline:hover{color:#f1f5f9;border-color:#6366f159;background:#6366f10f}.loader{width:20px;height:20px;border:3px solid rgba(255,255,255,.2);border-top-color:#fff;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-6px)}}@media(max-width:400px){.steps{margin-bottom:14px}.step-line{margin:0 4px 22px;min-width:12px}.step-label{font-size:.6rem}.screen-label{margin-bottom:12px}.icon-ms{font-size:2.25rem!important}.auth-form{gap:12px}}@media(prefers-reduced-motion:reduce){.icon-wrap,.loader{animation:none!important}}\n"] }]
464
464
  }], ctorParameters: () => [] });
465
465
 
466
466
  export { ForgotPasswordComponent };
467
- //# sourceMappingURL=avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs.map
467
+ //# sourceMappingURL=avora-labs-meta-forge-forgot-password.page-CWdWX-mj.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"avora-labs-meta-forge-forgot-password.page-CWdWX-mj.mjs","sources":["../../../projects/avora-meta-forge/src/lib/avora-meta-forge/pages/auth/forgot-password.page.ts"],"sourcesContent":["/**\n * Forgot Password Component\n *\n * Powered by AvoraMetaForge actions:\n * - Step 1: User enters email → fires mock-send-otp API → opens AMF OTP modal\n * - Modal verified → set-state marks otpVerified → page shows Step 2\n * - Step 2: User sets new password → mock-reset-password → back to login\n *\n * This component uses AmfAuthShellComponent for the shared visual shell.\n * Framework users can replicate this pattern by using AmfAuthShellComponent\n * with any custom content, or by building their own shell entirely.\n */\nimport { Component, inject, signal, OnDestroy, ViewChild } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { Router, RouterModule } from '@angular/router';\n\nimport { Subscription } from 'rxjs';\nimport { ActionDispatcherService } from '../../core/action-dispatcher.service';\nimport { MetaStateService } from '../../services/meta-state.service';\nimport { AmfAuthShellComponent } from '../../renderers/auth/amf-auth-shell.component';\nimport { FormRendererComponent } from '../../renderers/form/form-renderer.component';\nimport { FormMeta } from '../../models/meta.types';\nimport { APP_META_CONFIG_TOKEN } from '../../avora-meta-forge.provider';\ntype Step = 'email' | 'reset';\n\n@Component({\n selector: 'amf-forgot-password',\n standalone: true,\n imports: [FormsModule, RouterModule, AmfAuthShellComponent, FormRendererComponent],\n template: `\n <amf-auth-shell \n [brandName]=\"meta.auth?.builtInUI?.brandName || meta.app.name\"\n [brandTagline]=\"meta.auth?.builtInUI?.brandTagline || 'Recover your account'\"\n maxWidth=\"620px\">\n <!-- Step Indicator -->\n <div class=\"steps\">\n <div class=\"step\" [class.active]=\"currentStep() === 'email'\" [class.done]=\"currentStep() === 'reset'\">\n <div class=\"step-dot\">\n @if (currentStep() === 'reset') {\n <span class=\"ms step-icon\">check</span>\n } @else {\n <span>1</span>\n }\n </div>\n <span class=\"step-label\">Email</span>\n </div>\n <div class=\"step-line\" [class.done]=\"currentStep() === 'reset'\"></div>\n <div class=\"step\" [class.active]=\"currentStep() === 'reset'\">\n <div class=\"step-dot\"><span>2</span></div>\n <span class=\"step-label\">New Password</span>\n </div>\n </div>\n\n <!-- ── STEP 1: Email ── -->\n @if (currentStep() === 'email') {\n <div class=\"form-section\">\n <div class=\"screen-label\">\n <div class=\"icon-wrap\"><span class=\"ms icon-ms\">lock</span></div>\n <h2>Forgot your password?</h2>\n <p>Enter your email and we'll send a verification code.</p>\n </div>\n\n <div class=\"auth-form-container\">\n <amf-form-renderer \n [config]=\"emailForm\" \n (formSubmit)=\"onEmailSubmit($event)\"\n (formChange)=\"onEmailChange($event)\">\n </amf-form-renderer>\n\n @if (errorMsg()) {\n <div class=\"error-banner\">{{ errorMsg() }}</div>\n }\n\n <div class=\"action-row\">\n <button type=\"button\" class=\"auth-btn\" (click)=\"triggerEmailSubmit()\" [disabled]=\"loading() || !email\">\n @if (loading()) {\n <div class=\"loader\"></div>\n } @else {\n <span>Send Verification Code</span>\n }\n </button>\n <a routerLink=\"/login\" class=\"back-link-inline\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 12H5M12 19l-7-7 7-7\"/></svg>\n Back to Sign In\n </a>\n </div>\n </div>\n </div>\n }\n\n <!-- ── STEP 2: New Password (after OTP verified) ── -->\n @if (currentStep() === 'reset') {\n <div class=\"form-section\">\n <!-- Compact inline header for step 2 -->\n <div class=\"screen-label screen-label-sm\">\n <span class=\"ms icon-ms icon-ms-inline\">key</span>\n <div>\n <h2>Set a new password</h2>\n <p>Identity verified — choose a strong password.</p>\n </div>\n </div>\n\n <div class=\"auth-form-container\">\n <amf-form-renderer \n [config]=\"resetForm\" \n (formSubmit)=\"onResetSubmit($event)\"\n (formChange)=\"onResetChange($event)\">\n </amf-form-renderer>\n\n @if (confirmError) {\n <span class=\"field-error\" style=\"margin-top: -10px; display: block;\">Passwords don't match</span>\n }\n\n <!-- Strength bar: only show once user starts typing -->\n @if (newPassword) {\n <div class=\"strength-bar\">\n <div class=\"strength-track\">\n <div class=\"strength-fill\" [style.width]=\"strengthPct + '%'\" [class]=\"'strength-' + strengthLevel\"></div>\n </div>\n <span class=\"strength-label\">{{ strengthLabel }}</span>\n </div>\n }\n\n @if (errorMsg()) {\n <div class=\"error-banner\">{{ errorMsg() }}</div>\n }\n\n <!-- Inline action row: equal-width Submit + Back -->\n <div class=\"action-row\">\n <button type=\"button\" class=\"auth-btn\" (click)=\"triggerResetSubmit()\" [disabled]=\"loading() || !newPassword || !confirmPassword || confirmError\">\n @if (loading()) {\n <div class=\"loader\"></div>\n } @else {\n <span>Update Password</span>\n }\n </button>\n <a routerLink=\"/login\" class=\"back-link-inline\">\n <svg viewBox=\"0 0 24 24\"><path d=\"M19 12H5M12 19l-7-7 7-7\"/></svg>\n Back to Sign In\n </a>\n </div>\n </div>\n </div>\n }\n\n\n </amf-auth-shell>\n `,\n styles: [`\n :host { display: block; height: 100%; }\n\n /* ── Step Indicator ── */\n .steps {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0;\n margin-bottom: clamp(12px, 2.5vw, 20px);\n }\n .step {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 6px;\n }\n .step-dot {\n width: 32px; height: 32px;\n border-radius: 50%;\n border: 2px solid rgba(255,255,255,0.15);\n background: rgba(255,255,255,0.04);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.75rem;\n font-weight: 700;\n color: #64748b;\n transition: all 0.3s;\n }\n .step.active .step-dot {\n border-color: var(--app-primary, #6366f1);\n background: rgba(99,102,241,0.15);\n color: var(--app-primary, #6366f1);\n box-shadow: 0 0 16px var(--app-glow, rgba(99,102,241,0.4));\n }\n .step.done .step-dot {\n border-color: #10b981;\n background: rgba(16,185,129,0.15);\n color: #10b981;\n }\n .step-icon { font-size: 1rem !important; }\n .step-label {\n font-size: 0.7rem;\n color: #64748b;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n white-space: nowrap;\n }\n .step.active .step-label { color: #94a3b8; }\n .step-line {\n flex: 1;\n height: 2px;\n background: rgba(255,255,255,0.08);\n margin: 0 8px;\n margin-bottom: 22px;\n min-width: 24px;\n transition: background 0.3s;\n }\n .step-line.done { background: rgba(16,185,129,0.4); }\n\n /* ── Screen Label ── */\n .screen-label {\n text-align: center;\n margin-bottom: clamp(10px, 2vw, 16px);\n }\n /* Step 2 compact inline variant */\n .screen-label-sm {\n display: flex;\n align-items: center;\n gap: 12px;\n text-align: left;\n padding: 10px 14px;\n background: rgba(255,255,255,0.03);\n border: 1px solid rgba(255,255,255,0.07);\n border-radius: 12px;\n margin-bottom: clamp(10px, 2vw, 14px);\n }\n .screen-label-sm h2 {\n font-size: clamp(1rem, 3vw, 1.15rem) !important;\n margin-bottom: 2px !important;\n }\n .screen-label-sm p {\n font-size: clamp(0.75rem, 1.8vw, 0.82rem) !important;\n margin: 0;\n }\n .icon-ms-inline {\n font-size: 1.75rem !important;\n flex-shrink: 0;\n animation: float 3s ease-in-out infinite;\n }\n .icon-wrap {\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n animation: float 3s ease-in-out infinite;\n }\n .icon-ms {\n font-size: 2.1rem !important;\n font-variation-settings: 'FILL' 1, 'wght' 300, 'GRAD' 0, 'opsz' 48;\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n }\n .screen-label h2 {\n font-size: clamp(1.15rem, 4vw, 1.4rem);\n font-weight: 700;\n color: #f1f5f9;\n margin-bottom: 6px;\n }\n .screen-label p {\n font-size: clamp(0.8rem, 2vw, 0.875rem);\n color: #64748b;\n line-height: 1.5;\n }\n /* 2-col row for the two password fields */\n .pw-row {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n }\n @media (max-width: 460px) {\n .pw-row { grid-template-columns: 1fr; }\n .screen-label-sm { flex-direction: column; text-align: center; }\n }\n\n /* ── Form ── */\n .auth-form-container { display: flex; flex-direction: column; gap: clamp(10px, 2vw, 14px); }\n \n /* ── Map AMF Form classes to exactly match input-glass style ── */\n ::ng-deep .auth-form-container .amf-form { gap: clamp(10px, 2vw, 14px); }\n ::ng-deep .auth-form-container .amf-form-fields { gap: clamp(10px, 2vw, 14px); }\n ::ng-deep .auth-form-container .amf-field { display: flex; flex-direction: column; gap: 8px; }\n ::ng-deep .auth-form-container .field-label {\n font-size: 0.875rem !important;\n font-weight: 600 !important;\n color: #cbd5e1 !important;\n margin-bottom: 0 !important;\n }\n ::ng-deep .auth-form-container .field-input-wrapper {\n border-radius: 12px !important;\n border: 1px solid rgba(255,255,255,0.08) !important;\n background: rgba(255,255,255,0.04) !important;\n transition: all 0.25s !important;\n overflow: hidden;\n box-shadow: none !important;\n display: flex;\n align-items: center;\n }\n ::ng-deep .auth-form-container .field-input-wrapper:focus-within {\n border-color: var(--app-primary, #6366f1) !important;\n background: rgba(255,255,255,0.06) !important;\n box-shadow: 0 0 20px var(--app-glow, rgba(99,102,241,0.3)) !important;\n }\n ::ng-deep .auth-form-container .field-input {\n flex: 1;\n min-width: 0;\n padding: 13px 16px !important;\n border: none !important;\n background: transparent !important;\n font-size: clamp(0.9rem, 2vw, 1rem) !important;\n color: #f1f5f9 !important;\n }\n ::ng-deep .auth-form-container .field-input::placeholder { color: #64748b !important; }\n /* Eye toggle from FieldRendererComponent */\n ::ng-deep .auth-form-container .pwd-toggle-btn { color: #64748b !important; }\n ::ng-deep .auth-form-container .pwd-toggle-btn:hover { color: var(--app-primary, #6366f1) !important; }\n\n .field-error { font-size: 0.78rem; color: #ef4444; }\n\n /* ── Password Strength ── */\n .strength-bar { display: flex; align-items: center; gap: 10px; }\n .strength-track {\n flex: 1; height: 4px;\n background: rgba(255,255,255,0.07);\n border-radius: 2px;\n overflow: hidden;\n }\n .strength-fill {\n height: 100%;\n border-radius: 2px;\n transition: width 0.4s, background 0.4s;\n }\n .strength-weak { background: #ef4444; }\n .strength-fair { background: #f59e0b; }\n .strength-good { background: #10b981; }\n .strength-strong { background: #6366f1; }\n .strength-label { font-size: 0.75rem; color: #64748b; white-space: nowrap; }\n\n /* ── Button ── */\n .auth-btn {\n background: linear-gradient(135deg, var(--app-primary, #6366f1), var(--app-accent, #c084fc));\n color: white;\n padding: clamp(11px, 2.5vw, 14px);\n border: none;\n border-radius: 12px;\n font-size: clamp(0.9rem, 2vw, 1rem);\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4,0,0.2,1);\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n flex: 1; /* grows in action-row, fills full width standalone */\n min-width: 0;\n position: relative;\n overflow: hidden;\n }\n .auth-btn:hover:not(:disabled) {\n transform: translateY(-2px);\n box-shadow: 0 10px 30px -5px var(--app-glow, rgba(99,102,241,0.5));\n }\n .auth-btn:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }\n .btn-icon {\n width: 16px; height: 16px;\n fill: none; stroke: currentColor; stroke-width: 2.5;\n stroke-linecap: round; stroke-linejoin: round;\n flex-shrink: 0;\n }\n\n /* ── Error Banner ── */\n .error-banner {\n background: rgba(239,68,68,0.1);\n border: 1px solid rgba(239,68,68,0.3);\n border-radius: 10px;\n padding: 12px 16px;\n font-size: 0.875rem;\n color: #fca5a5;\n }\n\n /* ── Footer ── */\n .footer-note { text-align: center; margin-top: clamp(10px, 2vw, 18px); }\n .back-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 0.875rem;\n color: #64748b;\n font-weight: 500;\n transition: color 0.2s;\n text-decoration: none;\n }\n .back-link svg {\n width: 14px; height: 14px;\n fill: none; stroke: currentColor; stroke-width: 2.5;\n stroke-linecap: round; stroke-linejoin: round;\n }\n .back-link:hover { color: var(--app-primary, #6366f1); }\n\n /* ── Inline action row — both steps ── */\n .action-row {\n display: flex;\n align-items: stretch; /* same height naturally */\n gap: 10px;\n }\n /* Ghost back button — equal width to the primary btn via flex:1 */\n .back-link-inline {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n flex: 1; /* equal width with .auth-btn */\n min-width: 0;\n padding: clamp(11px, 2.5vw, 14px) 12px;\n border-radius: 12px;\n border: 1px solid rgba(255,255,255,0.1);\n background: rgba(255,255,255,0.04);\n color: #94a3b8;\n font-size: clamp(0.82rem, 2vw, 0.9rem);\n font-weight: 500;\n text-decoration: none;\n white-space: nowrap;\n transition: all 0.2s;\n }\n .back-link-inline svg {\n width: 13px; height: 13px;\n fill: none; stroke: currentColor; stroke-width: 2.5;\n stroke-linecap: round; stroke-linejoin: round;\n flex-shrink: 0;\n }\n .back-link-inline:hover {\n color: #f1f5f9;\n border-color: rgba(99,102,241,0.35);\n background: rgba(99,102,241,0.06);\n }\n\n /* ── Loader ── */\n .loader {\n width: 20px; height: 20px;\n border: 3px solid rgba(255,255,255,0.2);\n border-top-color: white;\n border-radius: 50%;\n animation: spin 0.8s linear infinite;\n }\n @keyframes spin { to { transform: rotate(360deg); } }\n @keyframes float {\n 0%, 100% { transform: translateY(0); }\n 50% { transform: translateY(-6px); }\n }\n\n /* ── Responsive: very small screens ── */\n @media (max-width: 400px) {\n .steps { margin-bottom: 14px; }\n .step-line { margin: 0 4px; margin-bottom: 22px; min-width: 12px; }\n .step-label { font-size: 0.6rem; }\n .screen-label { margin-bottom: 12px; }\n .icon-ms { font-size: 2.25rem !important; }\n .auth-form { gap: 12px; }\n }\n @media (prefers-reduced-motion: reduce) {\n .icon-wrap, .loader { animation: none !important; }\n }\n `]\n})\nexport class ForgotPasswordComponent implements OnDestroy {\n private readonly dispatcher = inject(ActionDispatcherService);\n private readonly stateService = inject(MetaStateService);\n private readonly router = inject(Router);\n protected meta: any = inject(APP_META_CONFIG_TOKEN, { optional: true }) || { app: { name: 'AvoraMetaForge' } };\n private readonly sub: Subscription;\n\n currentStep = signal<Step>('email');\n loading = signal(false);\n errorMsg = signal('');\n\n email = '';\n newPassword = '';\n confirmPassword = '';\n confirmError = false;\n\n // AMF Form Definitions\n emailForm: FormMeta = {\n id: 'emailForm',\n hideSubmit: true,\n fields: [\n {\n key: 'email',\n type: 'email',\n label: 'Email Address',\n placeholder: 'name@company.com',\n validators: [{ type: 'required' }]\n }\n ]\n };\n\n resetForm: FormMeta = {\n id: 'resetForm',\n hideSubmit: true,\n fields: [\n {\n key: 'newPassword',\n type: 'password',\n label: 'New Password',\n placeholder: 'Minimum 8 characters',\n validators: [{ type: 'required' }, { type: 'minLength', value: 8 }]\n },\n {\n key: 'confirmPassword',\n type: 'password',\n label: 'Confirm Password',\n placeholder: 'Re-enter password',\n validators: [{ type: 'required' }]\n }\n ]\n };\n\n constructor() {\n // Listen for modal events — when OTP is verified, advance to step 2\n this.sub = this.stateService.changes$.subscribe(change => {\n if (change.key === 'forgotPw.otpVerified' && change.newValue === true) {\n this.currentStep.set('reset');\n }\n });\n }\n\n ngOnDestroy() {\n this.sub.unsubscribe();\n this.stateService.clearNamespace('forgotPw');\n }\n\n get strengthPct(): number {\n const pw = this.newPassword;\n if (!pw) return 0;\n let score = 0;\n if (pw.length >= 8) score += 25;\n if (pw.length >= 12) score += 15;\n if (/[A-Z]/.test(pw)) score += 20;\n if (/[0-9]/.test(pw)) score += 20;\n if (/[^A-Za-z0-9]/.test(pw)) score += 20;\n return Math.min(score, 100);\n }\n get strengthLevel(): string {\n const p = this.strengthPct;\n if (p < 35) return 'weak';\n if (p < 60) return 'fair';\n if (p < 80) return 'good';\n return 'strong';\n }\n get strengthLabel(): string {\n const map: Record<string, string> = { weak: 'Weak', fair: 'Fair', good: 'Good', strong: 'Strong' };\n return this.strengthPct ? map[this.strengthLevel] : '';\n }\n\n checkConfirm(): void {\n this.confirmError = !!(this.confirmPassword && this.newPassword !== this.confirmPassword);\n }\n\n onEmailChange(values: any): void {\n this.email = values.email || '';\n }\n\n onResetChange(values: any): void {\n this.newPassword = values.newPassword || '';\n this.confirmPassword = values.confirmPassword || '';\n this.checkConfirm();\n }\n\n triggerEmailSubmit(): void {\n this.dispatcher.dispatch({ type: 'submit-form', config: { formId: 'emailForm' } });\n }\n\n triggerResetSubmit(): void {\n this.dispatcher.dispatch({ type: 'submit-form', config: { formId: 'resetForm' } });\n }\n\n onEmailSubmit(values: any): void {\n if (!values.email) return;\n\n this.loading.set(true);\n this.errorMsg.set('');\n\n // DEMO: calls mock-send-otp endpoint, then opens the OTP modal.\n // REAL: remove mock:true from 'mock-send-otp' and point it to your real endpoint.\n this.dispatcher.dispatch({\n type: 'dispatch-multiple',\n config: {\n mode: 'sequential',\n actions: [\n { type: 'api', config: { endpointId: 'mock-send-otp', body: { email: this.email } } },\n {\n type: 'open-modal',\n config: {\n title: 'Enter Verification Code',\n size: 'sm',\n disableCloseOnBackdrop: true,\n content: {\n type: 'form',\n config: {\n fields: [\n {\n key: 'code',\n label: 'We sent a 6-digit code to ' + this.email,\n type: 'otp',\n otpLength: 6,\n validators: [{ type: 'required' }, { type: 'minLength', value: 6 }]\n }\n ],\n submitLabel: 'Verify Code',\n onSubmit: {\n type: 'api',\n config: {\n endpointId: 'mock-verify-otp',\n body: 'formValue',\n storeInState: 'forgotPw.verifyResult'\n },\n then: {\n type: 'dispatch-multiple',\n config: {\n mode: 'sequential',\n actions: [\n { type: 'set-state', config: { key: 'forgotPw.otpVerified', value: true } },\n { type: 'close-modal', config: {} },\n { type: 'notify', config: { type: 'success', message: 'Code verified! Set your new password.' } }\n ]\n }\n },\n onError: {\n type: 'notify',\n config: { type: 'error', message: 'Invalid or expired code. Please try again.' }\n }\n }\n }\n }\n }\n }\n ]\n }\n }).finally(() => this.loading.set(false));\n }\n\n onResetSubmit(values: any): void {\n this.checkConfirm();\n if (!values.newPassword || this.confirmError) return;\n\n this.loading.set(true);\n this.errorMsg.set('');\n\n // DEMO: calls mock-reset-password endpoint.\n // REAL: remove mock:true from 'mock-reset-password' and point to your real endpoint.\n this.dispatcher.dispatch({\n type: 'api',\n config: {\n endpointId: 'mock-reset-password',\n body: { password: values.newPassword, resetToken: this.stateService.get('forgotPw.verifyResult.resetToken') }\n },\n then: {\n type: 'dispatch-multiple',\n config: {\n mode: 'sequential',\n actions: [\n { type: 'notify', config: { type: 'success', message: 'Password updated! Please log in with your new password.' } },\n { type: 'delay', config: { duration: 800 } },\n { type: 'navigate', config: { path: '/login' } }\n ]\n }\n },\n onError: {\n type: 'notify',\n config: { type: 'error', message: 'Password reset failed. Please try again.' }\n }\n }).finally(() => this.loading.set(false));\n }\n}\n"],"names":[],"mappings":"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"}