simpo-component-library 3.6.960 → 3.6.962

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.
@@ -22474,6 +22474,9 @@ class MyBookingsComponent {
22474
22474
  paidLabel(b) {
22475
22475
  return b.totalCollectedAtBooking && b.totalCollectedAtBooking > 0 ? `₹${b.totalCollectedAtBooking}` : 'Nothing — free';
22476
22476
  }
22477
+ servicePriceTotal(b) {
22478
+ return (b.services ?? []).reduce((sum, s) => sum + (s.price || 0), 0);
22479
+ }
22477
22480
  totalDue(b) {
22478
22481
  return (b.totalPayable ?? 0) + (b.homeVisitCharge ?? 0);
22479
22482
  }
@@ -22507,11 +22510,11 @@ class MyBookingsComponent {
22507
22510
  });
22508
22511
  }
22509
22512
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MyBookingsComponent, deps: [{ token: RestService }, { token: StorageServiceService }, { token: i6$1.MessageService }], target: i0.ɵɵFactoryTarget.Component }); }
22510
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MyBookingsComponent, isStandalone: true, selector: "simpo-my-bookings", providers: [MessageService], ngImport: i0, template: "<p-toast position=\"bottom-right\"></p-toast>\n\n<div class=\"mb-root\">\n <ng-container *ngIf=\"currentTab === 'LIST'\">\n <div class=\"mb-title\">My Bookings</div>\n\n <div class=\"mb-tabs\">\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'upcoming'\" (click)=\"setProfTab('upcoming')\">Upcoming</button>\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'past'\" (click)=\"setProfTab('past')\">Past</button>\n </div>\n\n <div class=\"mb-loading\" *ngIf=\"loading\">Loading your bookings\u2026</div>\n\n <div class=\"mb-rows\" *ngIf=\"!loading && !isEmpty\">\n <button type=\"button\" class=\"mb-row\" *ngFor=\"let b of rows\" (click)=\"viewBookingDetail(b)\">\n <div class=\"mb-row-stripe\" [ngClass]=\"b.mode === 'HOME_VISIT' ? 'stripe-home' : b.mode === 'VIDEO_CALL' ? 'stripe-video' : 'stripe-store'\"></div>\n <div class=\"mb-row-info\">\n <div class=\"mb-row-top\">\n <div class=\"mb-row-title\">{{title(b)}}</div>\n </div>\n <div class=\"mb-row-when\">{{when(b)}}</div>\n <div class=\"mb-row-detail\">{{detail(b)}}</div>\n </div>\n <div class=\"mb-row-end\">\n <span class=\"mb-status\" [ngClass]=\"statusClass(b.status)\">{{statusLabel(b.status)}}</span>\n </div>\n </button>\n </div>\n\n <div class=\"mb-empty\" *ngIf=\"isEmpty\">\n <mat-icon class=\"mb-empty-icon\">event_busy</mat-icon>\n <div class=\"mb-empty-title\">No {{profTab}} bookings yet.</div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"currentTab === 'DETAIL' && selected\">\n <button type=\"button\" class=\"mb-back\" (click)=\"backToList()\">\n <mat-icon>arrow_back</mat-icon> Back to My Bookings\n </button>\n\n <div class=\"mb-detail-card\">\n <div class=\"mb-detail-header\">\n <div class=\"mb-detail-title-row\">\n <div class=\"mb-detail-title\">{{title(selected)}}</div>\n <span class=\"mb-status\" [ngClass]=\"statusClass(selected.status)\">{{statusLabel(selected.status)}}</span>\n </div>\n <div class=\"mb-detail-when\">{{when(selected)}}</div>\n </div>\n\n <div class=\"mb-detail-rows\">\n <div class=\"mb-detail-row\" *ngIf=\"selected.services?.length\">\n <div class=\"mb-detail-k\">Services</div>\n <div class=\"mb-detail-v\">{{serviceNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.productLines?.length\">\n <div class=\"mb-detail-k\">Products</div>\n <div class=\"mb-detail-v\">{{productNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.customerDetail\">\n <div class=\"mb-detail-k\">Contact</div>\n <div class=\"mb-detail-v\">{{selected.customerDetail?.name}} \u00B7 {{selected.customerDetail?.phoneNumber}} \u00B7 {{selected.customerDetail?.email}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.mode === 'HOME_VISIT' && selected.addressDetails\">\n <div class=\"mb-detail-k\">Address</div>\n <div class=\"mb-detail-v\">{{selected.addressDetails?.addressLine1}}, {{selected.addressDetails?.city}}, {{selected.addressDetails?.state}} {{selected.addressDetails?.zipCode}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Total</div>\n <div class=\"mb-detail-v\">\u20B9{{totalDue(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Paid</div>\n <div class=\"mb-detail-v\">{{paidLabel(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"pendingAmount(selected) > 0\">\n <div class=\"mb-detail-k\">Pending at appointment</div>\n <div class=\"mb-detail-v\">\u20B9{{pendingAmount(selected)}}</div>\n </div>\n </div>\n\n <div class=\"mb-video-link\" *ngIf=\"selected.mode === 'VIDEO_CALL' && selected.videoCallLink && selected.status !== 'CANCELLED'\">\n <mat-icon>videocam</mat-icon>\n <a [href]=\"selected.videoCallLink\" target=\"_blank\">{{selected.videoCallLink}}</a>\n </div>\n\n <ng-container *ngIf=\"canCancelSelected\">\n <div class=\"mb-policy\" *ngIf=\"cancellationPolicy\">\n <div class=\"mb-policy-title\">{{cancellationPolicy.title}}</div>\n <div class=\"mb-policy-text\">{{cancellationPolicy.policyDetails}}</div>\n </div>\n <button type=\"button\" class=\"mb-cancel-btn\" [disabled]=\"cancelling\" (click)=\"cancelBooking()\">\n {{cancelling ? 'Cancelling\u2026' : 'Cancel booking'}}\n </button>\n </ng-container>\n\n <div class=\"mb-cancelled-note\" *ngIf=\"selected.status === 'CANCELLED'\">This booking has been cancelled.</div>\n </div>\n </ng-container>\n</div>\n", styles: [".mb-root{display:flex;flex-direction:column;gap:16px;padding:4px 0 24px}.mb-title{font-size:20px;font-weight:600;color:#1b2436}.mb-tabs{display:flex;background:#f5f2ee;border-radius:8px;padding:4px;gap:4px;width:fit-content}.mb-tab{border:none;background:transparent;border-radius:6px;padding:8px 18px;font-size:13.5px;font-weight:500;color:#8a94a3;cursor:pointer}.mb-tab.active{background:#fff;color:#1b2436;font-weight:600;box-shadow:0 1px 3px #00000012}.mb-loading{font-size:13.5px;color:#8a94a3;padding:20px 0}.mb-rows{display:flex;flex-direction:column;gap:12px}.mb-row{border:1px solid #EEE9E3;border-radius:10px;padding:16px 18px;display:flex;align-items:flex-start;gap:14px;background:#fff;cursor:pointer;text-align:left;width:100%}.mb-row-stripe{width:3px;align-self:stretch;border-radius:999px;flex:none}.stripe-home{background:#16233a}.stripe-video{background:#7c3a11}.stripe-store{background:#8a94a3}.mb-row-info{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.mb-row-title{font-size:14.5px;font-weight:600;color:#1b2436}.mb-row-when{font-size:12.5px;color:#6b7688}.mb-row-detail{font-size:12px;color:#8a94a3}.mb-row-end{flex:none}.mb-status{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;border-radius:999px;padding:4px 9px;white-space:nowrap}.status-confirmed{background:#e8f4ee;color:#1e7a4b}.status-completed{background:#f2eee9;color:#8a7c6c}.status-cancelled{background:#fbedec;color:#b4432e}.status-pending{background:#fdf3e3;color:#b36b00}.mb-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:50px 20px;text-align:center}.mb-empty-icon{font-size:40px!important;height:40px!important;width:40px!important;color:#c9b7a2!important}.mb-empty-title{font-size:14.5px;color:#8a94a3}.mb-back{display:flex;align-items:center;gap:6px;border:none;background:none;padding:0;cursor:pointer;font-size:12.5px;color:#7c3a11;margin-bottom:6px;width:fit-content}.mb-back mat-icon{font-size:16px!important;height:16px!important;width:16px!important}.mb-detail-card{border:1px solid #EEE9E3;border-radius:12px;padding:20px 22px;display:flex;flex-direction:column;gap:16px;background:#fff}.mb-detail-header{display:flex;flex-direction:column;gap:6px;padding-bottom:14px;border-bottom:1px solid #F0ECE7}.mb-detail-title-row{display:flex;align-items:center;gap:10px}.mb-detail-title{font-size:17px;font-weight:600;color:#1b2436}.mb-detail-when{font-size:13px;color:#6b7688}.mb-detail-rows{display:flex;flex-direction:column;gap:12px}.mb-detail-row{display:flex;justify-content:space-between;gap:16px;font-size:13px}.mb-detail-k{color:#8a94a3;flex:none}.mb-detail-v{color:#1b2436;font-weight:500;text-align:right}.mb-video-link{display:flex;align-items:center;gap:10px;padding:12px 14px;background:#f2f9f5;border-radius:8px;font-size:13px;color:#2c6a4b}.mb-video-link mat-icon{color:#1e7a4b!important;flex:none}.mb-policy{background:#fbfaf8;border:1px solid #EDE8E2;border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:4px}.mb-policy-title{font-size:12px;font-weight:600;color:#a08b72;text-transform:uppercase;letter-spacing:.06em}.mb-policy-text{font-size:12.5px;line-height:1.6;color:#5f6b7c}.mb-cancel-btn{height:46px;border:1.5px solid #E3CFC9;border-radius:8px;background:#fff;color:#b4432e;font-size:13.5px;font-weight:600;cursor:pointer}.mb-cancel-btn:disabled{opacity:.6;cursor:not-allowed}.mb-cancelled-note{font-size:13px;color:#b4432e;font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
22513
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MyBookingsComponent, isStandalone: true, selector: "simpo-my-bookings", providers: [MessageService], ngImport: i0, template: "<p-toast position=\"bottom-right\"></p-toast>\n\n<div class=\"mb-root\">\n <ng-container *ngIf=\"currentTab === 'LIST'\">\n <div class=\"mb-title\">My Bookings</div>\n\n <div class=\"mb-tabs\">\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'upcoming'\" (click)=\"setProfTab('upcoming')\">Upcoming</button>\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'past'\" (click)=\"setProfTab('past')\">Past</button>\n </div>\n\n <div class=\"mb-loading\" *ngIf=\"loading\">Loading your bookings\u2026</div>\n\n <div class=\"mb-rows\" *ngIf=\"!loading && !isEmpty\">\n <button type=\"button\" class=\"mb-row\" *ngFor=\"let b of rows\" (click)=\"viewBookingDetail(b)\">\n <div class=\"mb-row-stripe\" [ngClass]=\"b.mode === 'HOME_VISIT' ? 'stripe-home' : b.mode === 'VIDEO_CALL' ? 'stripe-video' : 'stripe-store'\"></div>\n <div class=\"mb-row-info\">\n <div class=\"mb-row-top\">\n <div class=\"mb-row-title\">{{title(b)}}</div>\n </div>\n <div class=\"mb-row-when\">{{when(b)}}</div>\n <div class=\"mb-row-detail\">{{detail(b)}}</div>\n </div>\n <div class=\"mb-row-end\">\n <span class=\"mb-status\" [ngClass]=\"statusClass(b.status)\">{{statusLabel(b.status)}}</span>\n </div>\n </button>\n </div>\n\n <div class=\"mb-empty\" *ngIf=\"isEmpty\">\n <mat-icon class=\"mb-empty-icon\">event_busy</mat-icon>\n <div class=\"mb-empty-title\">No {{profTab}} bookings yet.</div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"currentTab === 'DETAIL' && selected\">\n <button type=\"button\" class=\"mb-back\" (click)=\"backToList()\">\n <mat-icon>arrow_back</mat-icon> Back to My Bookings\n </button>\n\n <div class=\"mb-detail-card\">\n <div class=\"mb-detail-header\">\n <div class=\"mb-detail-title-row\">\n <div class=\"mb-detail-title\">{{title(selected)}}</div>\n <span class=\"mb-status\" [ngClass]=\"statusClass(selected.status)\">{{statusLabel(selected.status)}}</span>\n </div>\n <div class=\"mb-detail-when\">{{when(selected)}}</div>\n </div>\n\n <div class=\"mb-detail-rows\">\n <div class=\"mb-detail-row\" *ngIf=\"selected.services?.length\">\n <div class=\"mb-detail-k\">Services</div>\n <div class=\"mb-detail-v\">{{serviceNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.productLines?.length\">\n <div class=\"mb-detail-k\">Products</div>\n <div class=\"mb-detail-v\">{{productNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.customerDetail\">\n <div class=\"mb-detail-k\">Contact</div>\n <div class=\"mb-detail-v\">{{selected.customerDetail?.name}} \u00B7 {{selected.customerDetail?.phoneNumber}} \u00B7 {{selected.customerDetail?.email}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.mode === 'HOME_VISIT' && selected.addressDetails\">\n <div class=\"mb-detail-k\">Address</div>\n <div class=\"mb-detail-v\">{{selected.addressDetails?.addressLine1}}, {{selected.addressDetails?.city}}, {{selected.addressDetails?.state}} {{selected.addressDetails?.zipCode}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"servicePriceTotal(selected) > 0\">\n <div class=\"mb-detail-k\">Service price</div>\n <div class=\"mb-detail-v\">\u20B9{{servicePriceTotal(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.homeVisitCharge\">\n <div class=\"mb-detail-k\">Home visit charge</div>\n <div class=\"mb-detail-v\">\u20B9{{selected.homeVisitCharge}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Total</div>\n <div class=\"mb-detail-v\">\u20B9{{totalDue(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Paid</div>\n <div class=\"mb-detail-v\">{{paidLabel(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"pendingAmount(selected) > 0\">\n <div class=\"mb-detail-k\">Pending at appointment</div>\n <div class=\"mb-detail-v\">\u20B9{{pendingAmount(selected)}}</div>\n </div>\n </div>\n\n <div class=\"mb-video-link\" *ngIf=\"selected.mode === 'VIDEO_CALL' && selected.videoCallLink && selected.status !== 'CANCELLED'\">\n <mat-icon>videocam</mat-icon>\n <a [href]=\"selected.videoCallLink\" target=\"_blank\">{{selected.videoCallLink}}</a>\n </div>\n\n <ng-container *ngIf=\"canCancelSelected\">\n <div class=\"mb-policy\" *ngIf=\"cancellationPolicy\">\n <div class=\"mb-policy-title\">{{cancellationPolicy.title}}</div>\n <div class=\"mb-policy-text\">{{cancellationPolicy.policyDetails}}</div>\n </div>\n <button type=\"button\" class=\"mb-cancel-btn\" [disabled]=\"cancelling\" (click)=\"cancelBooking()\">\n {{cancelling ? 'Cancelling\u2026' : 'Cancel booking'}}\n </button>\n </ng-container>\n\n <div class=\"mb-cancelled-note\" *ngIf=\"selected.status === 'CANCELLED'\">This booking has been cancelled.</div>\n </div>\n </ng-container>\n</div>\n", styles: [".mb-root{display:flex;flex-direction:column;gap:16px;padding:4px 0 24px}.mb-title{font-size:20px;font-weight:600;color:#1b2436}.mb-tabs{display:flex;background:#f5f2ee;border-radius:8px;padding:4px;gap:4px;width:fit-content}.mb-tab{border:none;background:transparent;border-radius:6px;padding:8px 18px;font-size:13.5px;font-weight:500;color:#8a94a3;cursor:pointer}.mb-tab.active{background:#fff;color:#1b2436;font-weight:600;box-shadow:0 1px 3px #00000012}.mb-loading{font-size:13.5px;color:#8a94a3;padding:20px 0}.mb-rows{display:flex;flex-direction:column;gap:12px}.mb-row{border:1px solid #EEE9E3;border-radius:10px;padding:16px 18px;display:flex;align-items:flex-start;gap:14px;background:#fff;cursor:pointer;text-align:left;width:100%}.mb-row-stripe{width:3px;align-self:stretch;border-radius:999px;flex:none}.stripe-home{background:#16233a}.stripe-video{background:#7c3a11}.stripe-store{background:#8a94a3}.mb-row-info{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.mb-row-title{font-size:14.5px;font-weight:600;color:#1b2436}.mb-row-when{font-size:12.5px;color:#6b7688}.mb-row-detail{font-size:12px;color:#8a94a3}.mb-row-end{flex:none}.mb-status{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;border-radius:999px;padding:4px 9px;white-space:nowrap}.status-confirmed{background:#e8f4ee;color:#1e7a4b}.status-completed{background:#f2eee9;color:#8a7c6c}.status-cancelled{background:#fbedec;color:#b4432e}.status-pending{background:#fdf3e3;color:#b36b00}.mb-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:50px 20px;text-align:center}.mb-empty-icon{font-size:40px!important;height:40px!important;width:40px!important;color:#c9b7a2!important}.mb-empty-title{font-size:14.5px;color:#8a94a3}.mb-back{display:flex;align-items:center;gap:6px;border:none;background:none;padding:0;cursor:pointer;font-size:12.5px;color:#7c3a11;margin-bottom:6px;width:fit-content}.mb-back mat-icon{font-size:16px!important;height:16px!important;width:16px!important}.mb-detail-card{border:1px solid #EEE9E3;border-radius:12px;padding:20px 22px;display:flex;flex-direction:column;gap:16px;background:#fff}.mb-detail-header{display:flex;flex-direction:column;gap:6px;padding-bottom:14px;border-bottom:1px solid #F0ECE7}.mb-detail-title-row{display:flex;align-items:center;gap:10px}.mb-detail-title{font-size:17px;font-weight:600;color:#1b2436}.mb-detail-when{font-size:13px;color:#6b7688}.mb-detail-rows{display:flex;flex-direction:column;gap:12px}.mb-detail-row{display:flex;justify-content:space-between;gap:16px;font-size:13px}.mb-detail-k{color:#8a94a3;flex:none}.mb-detail-v{color:#1b2436;font-weight:500;text-align:right}.mb-video-link{display:flex;align-items:center;gap:10px;padding:12px 14px;background:#f2f9f5;border-radius:8px;font-size:13px;color:#2c6a4b}.mb-video-link mat-icon{color:#1e7a4b!important;flex:none}.mb-policy{background:#fbfaf8;border:1px solid #EDE8E2;border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:4px}.mb-policy-title{font-size:12px;font-weight:600;color:#a08b72;text-transform:uppercase;letter-spacing:.06em}.mb-policy-text{font-size:12.5px;line-height:1.6;color:#5f6b7c}.mb-cancel-btn{height:46px;border:1.5px solid #E3CFC9;border-radius:8px;background:#fff;color:#b4432e;font-size:13.5px;font-weight:600;cursor:pointer}.mb-cancel-btn:disabled{opacity:.6;cursor:not-allowed}.mb-cancelled-note{font-size:13px;color:#b4432e;font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] }); }
22511
22514
  }
22512
22515
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MyBookingsComponent, decorators: [{
22513
22516
  type: Component,
22514
- args: [{ selector: 'simpo-my-bookings', standalone: true, imports: [CommonModule, MatIconModule, ToastModule], providers: [MessageService], template: "<p-toast position=\"bottom-right\"></p-toast>\n\n<div class=\"mb-root\">\n <ng-container *ngIf=\"currentTab === 'LIST'\">\n <div class=\"mb-title\">My Bookings</div>\n\n <div class=\"mb-tabs\">\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'upcoming'\" (click)=\"setProfTab('upcoming')\">Upcoming</button>\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'past'\" (click)=\"setProfTab('past')\">Past</button>\n </div>\n\n <div class=\"mb-loading\" *ngIf=\"loading\">Loading your bookings\u2026</div>\n\n <div class=\"mb-rows\" *ngIf=\"!loading && !isEmpty\">\n <button type=\"button\" class=\"mb-row\" *ngFor=\"let b of rows\" (click)=\"viewBookingDetail(b)\">\n <div class=\"mb-row-stripe\" [ngClass]=\"b.mode === 'HOME_VISIT' ? 'stripe-home' : b.mode === 'VIDEO_CALL' ? 'stripe-video' : 'stripe-store'\"></div>\n <div class=\"mb-row-info\">\n <div class=\"mb-row-top\">\n <div class=\"mb-row-title\">{{title(b)}}</div>\n </div>\n <div class=\"mb-row-when\">{{when(b)}}</div>\n <div class=\"mb-row-detail\">{{detail(b)}}</div>\n </div>\n <div class=\"mb-row-end\">\n <span class=\"mb-status\" [ngClass]=\"statusClass(b.status)\">{{statusLabel(b.status)}}</span>\n </div>\n </button>\n </div>\n\n <div class=\"mb-empty\" *ngIf=\"isEmpty\">\n <mat-icon class=\"mb-empty-icon\">event_busy</mat-icon>\n <div class=\"mb-empty-title\">No {{profTab}} bookings yet.</div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"currentTab === 'DETAIL' && selected\">\n <button type=\"button\" class=\"mb-back\" (click)=\"backToList()\">\n <mat-icon>arrow_back</mat-icon> Back to My Bookings\n </button>\n\n <div class=\"mb-detail-card\">\n <div class=\"mb-detail-header\">\n <div class=\"mb-detail-title-row\">\n <div class=\"mb-detail-title\">{{title(selected)}}</div>\n <span class=\"mb-status\" [ngClass]=\"statusClass(selected.status)\">{{statusLabel(selected.status)}}</span>\n </div>\n <div class=\"mb-detail-when\">{{when(selected)}}</div>\n </div>\n\n <div class=\"mb-detail-rows\">\n <div class=\"mb-detail-row\" *ngIf=\"selected.services?.length\">\n <div class=\"mb-detail-k\">Services</div>\n <div class=\"mb-detail-v\">{{serviceNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.productLines?.length\">\n <div class=\"mb-detail-k\">Products</div>\n <div class=\"mb-detail-v\">{{productNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.customerDetail\">\n <div class=\"mb-detail-k\">Contact</div>\n <div class=\"mb-detail-v\">{{selected.customerDetail?.name}} \u00B7 {{selected.customerDetail?.phoneNumber}} \u00B7 {{selected.customerDetail?.email}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.mode === 'HOME_VISIT' && selected.addressDetails\">\n <div class=\"mb-detail-k\">Address</div>\n <div class=\"mb-detail-v\">{{selected.addressDetails?.addressLine1}}, {{selected.addressDetails?.city}}, {{selected.addressDetails?.state}} {{selected.addressDetails?.zipCode}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Total</div>\n <div class=\"mb-detail-v\">\u20B9{{totalDue(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Paid</div>\n <div class=\"mb-detail-v\">{{paidLabel(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"pendingAmount(selected) > 0\">\n <div class=\"mb-detail-k\">Pending at appointment</div>\n <div class=\"mb-detail-v\">\u20B9{{pendingAmount(selected)}}</div>\n </div>\n </div>\n\n <div class=\"mb-video-link\" *ngIf=\"selected.mode === 'VIDEO_CALL' && selected.videoCallLink && selected.status !== 'CANCELLED'\">\n <mat-icon>videocam</mat-icon>\n <a [href]=\"selected.videoCallLink\" target=\"_blank\">{{selected.videoCallLink}}</a>\n </div>\n\n <ng-container *ngIf=\"canCancelSelected\">\n <div class=\"mb-policy\" *ngIf=\"cancellationPolicy\">\n <div class=\"mb-policy-title\">{{cancellationPolicy.title}}</div>\n <div class=\"mb-policy-text\">{{cancellationPolicy.policyDetails}}</div>\n </div>\n <button type=\"button\" class=\"mb-cancel-btn\" [disabled]=\"cancelling\" (click)=\"cancelBooking()\">\n {{cancelling ? 'Cancelling\u2026' : 'Cancel booking'}}\n </button>\n </ng-container>\n\n <div class=\"mb-cancelled-note\" *ngIf=\"selected.status === 'CANCELLED'\">This booking has been cancelled.</div>\n </div>\n </ng-container>\n</div>\n", styles: [".mb-root{display:flex;flex-direction:column;gap:16px;padding:4px 0 24px}.mb-title{font-size:20px;font-weight:600;color:#1b2436}.mb-tabs{display:flex;background:#f5f2ee;border-radius:8px;padding:4px;gap:4px;width:fit-content}.mb-tab{border:none;background:transparent;border-radius:6px;padding:8px 18px;font-size:13.5px;font-weight:500;color:#8a94a3;cursor:pointer}.mb-tab.active{background:#fff;color:#1b2436;font-weight:600;box-shadow:0 1px 3px #00000012}.mb-loading{font-size:13.5px;color:#8a94a3;padding:20px 0}.mb-rows{display:flex;flex-direction:column;gap:12px}.mb-row{border:1px solid #EEE9E3;border-radius:10px;padding:16px 18px;display:flex;align-items:flex-start;gap:14px;background:#fff;cursor:pointer;text-align:left;width:100%}.mb-row-stripe{width:3px;align-self:stretch;border-radius:999px;flex:none}.stripe-home{background:#16233a}.stripe-video{background:#7c3a11}.stripe-store{background:#8a94a3}.mb-row-info{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.mb-row-title{font-size:14.5px;font-weight:600;color:#1b2436}.mb-row-when{font-size:12.5px;color:#6b7688}.mb-row-detail{font-size:12px;color:#8a94a3}.mb-row-end{flex:none}.mb-status{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;border-radius:999px;padding:4px 9px;white-space:nowrap}.status-confirmed{background:#e8f4ee;color:#1e7a4b}.status-completed{background:#f2eee9;color:#8a7c6c}.status-cancelled{background:#fbedec;color:#b4432e}.status-pending{background:#fdf3e3;color:#b36b00}.mb-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:50px 20px;text-align:center}.mb-empty-icon{font-size:40px!important;height:40px!important;width:40px!important;color:#c9b7a2!important}.mb-empty-title{font-size:14.5px;color:#8a94a3}.mb-back{display:flex;align-items:center;gap:6px;border:none;background:none;padding:0;cursor:pointer;font-size:12.5px;color:#7c3a11;margin-bottom:6px;width:fit-content}.mb-back mat-icon{font-size:16px!important;height:16px!important;width:16px!important}.mb-detail-card{border:1px solid #EEE9E3;border-radius:12px;padding:20px 22px;display:flex;flex-direction:column;gap:16px;background:#fff}.mb-detail-header{display:flex;flex-direction:column;gap:6px;padding-bottom:14px;border-bottom:1px solid #F0ECE7}.mb-detail-title-row{display:flex;align-items:center;gap:10px}.mb-detail-title{font-size:17px;font-weight:600;color:#1b2436}.mb-detail-when{font-size:13px;color:#6b7688}.mb-detail-rows{display:flex;flex-direction:column;gap:12px}.mb-detail-row{display:flex;justify-content:space-between;gap:16px;font-size:13px}.mb-detail-k{color:#8a94a3;flex:none}.mb-detail-v{color:#1b2436;font-weight:500;text-align:right}.mb-video-link{display:flex;align-items:center;gap:10px;padding:12px 14px;background:#f2f9f5;border-radius:8px;font-size:13px;color:#2c6a4b}.mb-video-link mat-icon{color:#1e7a4b!important;flex:none}.mb-policy{background:#fbfaf8;border:1px solid #EDE8E2;border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:4px}.mb-policy-title{font-size:12px;font-weight:600;color:#a08b72;text-transform:uppercase;letter-spacing:.06em}.mb-policy-text{font-size:12.5px;line-height:1.6;color:#5f6b7c}.mb-cancel-btn{height:46px;border:1.5px solid #E3CFC9;border-radius:8px;background:#fff;color:#b4432e;font-size:13.5px;font-weight:600;cursor:pointer}.mb-cancel-btn:disabled{opacity:.6;cursor:not-allowed}.mb-cancelled-note{font-size:13px;color:#b4432e;font-weight:600}\n"] }]
22517
+ args: [{ selector: 'simpo-my-bookings', standalone: true, imports: [CommonModule, MatIconModule, ToastModule], providers: [MessageService], template: "<p-toast position=\"bottom-right\"></p-toast>\n\n<div class=\"mb-root\">\n <ng-container *ngIf=\"currentTab === 'LIST'\">\n <div class=\"mb-title\">My Bookings</div>\n\n <div class=\"mb-tabs\">\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'upcoming'\" (click)=\"setProfTab('upcoming')\">Upcoming</button>\n <button type=\"button\" class=\"mb-tab\" [class.active]=\"profTab === 'past'\" (click)=\"setProfTab('past')\">Past</button>\n </div>\n\n <div class=\"mb-loading\" *ngIf=\"loading\">Loading your bookings\u2026</div>\n\n <div class=\"mb-rows\" *ngIf=\"!loading && !isEmpty\">\n <button type=\"button\" class=\"mb-row\" *ngFor=\"let b of rows\" (click)=\"viewBookingDetail(b)\">\n <div class=\"mb-row-stripe\" [ngClass]=\"b.mode === 'HOME_VISIT' ? 'stripe-home' : b.mode === 'VIDEO_CALL' ? 'stripe-video' : 'stripe-store'\"></div>\n <div class=\"mb-row-info\">\n <div class=\"mb-row-top\">\n <div class=\"mb-row-title\">{{title(b)}}</div>\n </div>\n <div class=\"mb-row-when\">{{when(b)}}</div>\n <div class=\"mb-row-detail\">{{detail(b)}}</div>\n </div>\n <div class=\"mb-row-end\">\n <span class=\"mb-status\" [ngClass]=\"statusClass(b.status)\">{{statusLabel(b.status)}}</span>\n </div>\n </button>\n </div>\n\n <div class=\"mb-empty\" *ngIf=\"isEmpty\">\n <mat-icon class=\"mb-empty-icon\">event_busy</mat-icon>\n <div class=\"mb-empty-title\">No {{profTab}} bookings yet.</div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"currentTab === 'DETAIL' && selected\">\n <button type=\"button\" class=\"mb-back\" (click)=\"backToList()\">\n <mat-icon>arrow_back</mat-icon> Back to My Bookings\n </button>\n\n <div class=\"mb-detail-card\">\n <div class=\"mb-detail-header\">\n <div class=\"mb-detail-title-row\">\n <div class=\"mb-detail-title\">{{title(selected)}}</div>\n <span class=\"mb-status\" [ngClass]=\"statusClass(selected.status)\">{{statusLabel(selected.status)}}</span>\n </div>\n <div class=\"mb-detail-when\">{{when(selected)}}</div>\n </div>\n\n <div class=\"mb-detail-rows\">\n <div class=\"mb-detail-row\" *ngIf=\"selected.services?.length\">\n <div class=\"mb-detail-k\">Services</div>\n <div class=\"mb-detail-v\">{{serviceNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.productLines?.length\">\n <div class=\"mb-detail-k\">Products</div>\n <div class=\"mb-detail-v\">{{productNames(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.customerDetail\">\n <div class=\"mb-detail-k\">Contact</div>\n <div class=\"mb-detail-v\">{{selected.customerDetail?.name}} \u00B7 {{selected.customerDetail?.phoneNumber}} \u00B7 {{selected.customerDetail?.email}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.mode === 'HOME_VISIT' && selected.addressDetails\">\n <div class=\"mb-detail-k\">Address</div>\n <div class=\"mb-detail-v\">{{selected.addressDetails?.addressLine1}}, {{selected.addressDetails?.city}}, {{selected.addressDetails?.state}} {{selected.addressDetails?.zipCode}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"servicePriceTotal(selected) > 0\">\n <div class=\"mb-detail-k\">Service price</div>\n <div class=\"mb-detail-v\">\u20B9{{servicePriceTotal(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"selected.homeVisitCharge\">\n <div class=\"mb-detail-k\">Home visit charge</div>\n <div class=\"mb-detail-v\">\u20B9{{selected.homeVisitCharge}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Total</div>\n <div class=\"mb-detail-v\">\u20B9{{totalDue(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\">\n <div class=\"mb-detail-k\">Paid</div>\n <div class=\"mb-detail-v\">{{paidLabel(selected)}}</div>\n </div>\n <div class=\"mb-detail-row\" *ngIf=\"pendingAmount(selected) > 0\">\n <div class=\"mb-detail-k\">Pending at appointment</div>\n <div class=\"mb-detail-v\">\u20B9{{pendingAmount(selected)}}</div>\n </div>\n </div>\n\n <div class=\"mb-video-link\" *ngIf=\"selected.mode === 'VIDEO_CALL' && selected.videoCallLink && selected.status !== 'CANCELLED'\">\n <mat-icon>videocam</mat-icon>\n <a [href]=\"selected.videoCallLink\" target=\"_blank\">{{selected.videoCallLink}}</a>\n </div>\n\n <ng-container *ngIf=\"canCancelSelected\">\n <div class=\"mb-policy\" *ngIf=\"cancellationPolicy\">\n <div class=\"mb-policy-title\">{{cancellationPolicy.title}}</div>\n <div class=\"mb-policy-text\">{{cancellationPolicy.policyDetails}}</div>\n </div>\n <button type=\"button\" class=\"mb-cancel-btn\" [disabled]=\"cancelling\" (click)=\"cancelBooking()\">\n {{cancelling ? 'Cancelling\u2026' : 'Cancel booking'}}\n </button>\n </ng-container>\n\n <div class=\"mb-cancelled-note\" *ngIf=\"selected.status === 'CANCELLED'\">This booking has been cancelled.</div>\n </div>\n </ng-container>\n</div>\n", styles: [".mb-root{display:flex;flex-direction:column;gap:16px;padding:4px 0 24px}.mb-title{font-size:20px;font-weight:600;color:#1b2436}.mb-tabs{display:flex;background:#f5f2ee;border-radius:8px;padding:4px;gap:4px;width:fit-content}.mb-tab{border:none;background:transparent;border-radius:6px;padding:8px 18px;font-size:13.5px;font-weight:500;color:#8a94a3;cursor:pointer}.mb-tab.active{background:#fff;color:#1b2436;font-weight:600;box-shadow:0 1px 3px #00000012}.mb-loading{font-size:13.5px;color:#8a94a3;padding:20px 0}.mb-rows{display:flex;flex-direction:column;gap:12px}.mb-row{border:1px solid #EEE9E3;border-radius:10px;padding:16px 18px;display:flex;align-items:flex-start;gap:14px;background:#fff;cursor:pointer;text-align:left;width:100%}.mb-row-stripe{width:3px;align-self:stretch;border-radius:999px;flex:none}.stripe-home{background:#16233a}.stripe-video{background:#7c3a11}.stripe-store{background:#8a94a3}.mb-row-info{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.mb-row-title{font-size:14.5px;font-weight:600;color:#1b2436}.mb-row-when{font-size:12.5px;color:#6b7688}.mb-row-detail{font-size:12px;color:#8a94a3}.mb-row-end{flex:none}.mb-status{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;border-radius:999px;padding:4px 9px;white-space:nowrap}.status-confirmed{background:#e8f4ee;color:#1e7a4b}.status-completed{background:#f2eee9;color:#8a7c6c}.status-cancelled{background:#fbedec;color:#b4432e}.status-pending{background:#fdf3e3;color:#b36b00}.mb-empty{display:flex;flex-direction:column;align-items:center;gap:10px;padding:50px 20px;text-align:center}.mb-empty-icon{font-size:40px!important;height:40px!important;width:40px!important;color:#c9b7a2!important}.mb-empty-title{font-size:14.5px;color:#8a94a3}.mb-back{display:flex;align-items:center;gap:6px;border:none;background:none;padding:0;cursor:pointer;font-size:12.5px;color:#7c3a11;margin-bottom:6px;width:fit-content}.mb-back mat-icon{font-size:16px!important;height:16px!important;width:16px!important}.mb-detail-card{border:1px solid #EEE9E3;border-radius:12px;padding:20px 22px;display:flex;flex-direction:column;gap:16px;background:#fff}.mb-detail-header{display:flex;flex-direction:column;gap:6px;padding-bottom:14px;border-bottom:1px solid #F0ECE7}.mb-detail-title-row{display:flex;align-items:center;gap:10px}.mb-detail-title{font-size:17px;font-weight:600;color:#1b2436}.mb-detail-when{font-size:13px;color:#6b7688}.mb-detail-rows{display:flex;flex-direction:column;gap:12px}.mb-detail-row{display:flex;justify-content:space-between;gap:16px;font-size:13px}.mb-detail-k{color:#8a94a3;flex:none}.mb-detail-v{color:#1b2436;font-weight:500;text-align:right}.mb-video-link{display:flex;align-items:center;gap:10px;padding:12px 14px;background:#f2f9f5;border-radius:8px;font-size:13px;color:#2c6a4b}.mb-video-link mat-icon{color:#1e7a4b!important;flex:none}.mb-policy{background:#fbfaf8;border:1px solid #EDE8E2;border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:4px}.mb-policy-title{font-size:12px;font-weight:600;color:#a08b72;text-transform:uppercase;letter-spacing:.06em}.mb-policy-text{font-size:12.5px;line-height:1.6;color:#5f6b7c}.mb-cancel-btn{height:46px;border:1.5px solid #E3CFC9;border-radius:8px;background:#fff;color:#b4432e;font-size:13.5px;font-weight:600;cursor:pointer}.mb-cancel-btn:disabled{opacity:.6;cursor:not-allowed}.mb-cancelled-note{font-size:13px;color:#b4432e;font-weight:600}\n"] }]
22515
22518
  }], ctorParameters: () => [{ type: RestService }, { type: StorageServiceService }, { type: i6$1.MessageService }] });
22516
22519
 
22517
22520
  class PassbookTransactionsComponent {
@@ -23716,19 +23719,9 @@ class VerifyComponent extends BaseSection {
23716
23719
  this.restService.getAppointmentPaymentStatus(orderId).subscribe((response) => {
23717
23720
  localStorage.removeItem("appointmentPaymentId");
23718
23721
  this.paymentStatus = 'SUCCESS';
23719
- // setTimeout(() => {
23720
- // this.router.navigate(['/profile']);
23721
- // }, 3000);
23722
- // Swal.fire({
23723
- // icon: "success",
23724
- // title: "Hurray",
23725
- // text: "Payment Successful",
23726
- // confirmButtonText: "See Details"
23727
- // }).then((response) => {
23728
- // if (response.isConfirmed) {
23729
- // this.router.navigate(['/profile'], {queryParams: {tab: 'Scheme Passbook'}});
23730
- // }
23731
- // })
23722
+ setTimeout(() => {
23723
+ this.router.navigate(['/profile']);
23724
+ }, 3000);
23732
23725
  }, (error) => {
23733
23726
  if (this.APPOINTMENT_API_COUNT >= this.MAX_API_COUNT) {
23734
23727
  // Swal.fire({
@@ -25405,6 +25398,7 @@ class AppointmentBookingComponent extends BaseSection {
25405
25398
  this.barWidth = '';
25406
25399
  this.showCancellationPolicy = false;
25407
25400
  this.showReducingPolicy = false;
25401
+ this.businessSettings = null;
25408
25402
  this.selectedMode = 'STORE_VISIT';
25409
25403
  this.modePinned = false;
25410
25404
  // Cart of services picked in serviceListing - clicking a card toggles membership. This is a
@@ -25466,6 +25460,42 @@ class AppointmentBookingComponent extends BaseSection {
25466
25460
  get accentColor() {
25467
25461
  return this.data?.styles?.background?.accentColor || null;
25468
25462
  }
25463
+ get homeVisitCharge() {
25464
+ return this.selectedMode === 'HOME_VISIT' ? (this.businessSettings?.homeVisitCharge ?? 0) : 0;
25465
+ }
25466
+ /** Price for one resolved-line service, looked up from `cartServices` (the service-listing
25467
+ * selection, which carries `priceDetails`) since `resolvedLines[].services` only carries id+name
25468
+ * back from the slot-resolution API. */
25469
+ servicePrice(serviceId) {
25470
+ return this.cartServices.find((s) => s.serviceId === serviceId)?.priceDetails?.price ?? 0;
25471
+ }
25472
+ lineServiceTotal(line) {
25473
+ return (line.services || []).reduce((sum, s) => sum + this.servicePrice(s.id), 0);
25474
+ }
25475
+ get servicesSubtotal() {
25476
+ return this.resolvedLines.reduce((sum, l) => sum + this.lineServiceTotal(l), 0);
25477
+ }
25478
+ get reviewTotal() {
25479
+ return this.servicesSubtotal + this.homeVisitCharge;
25480
+ }
25481
+ get bookingTotal() {
25482
+ return (this.bookingGroup?.totalPayable ?? 0) + (this.bookingGroup?.homeVisitCharge ?? 0);
25483
+ }
25484
+ get bookingPaid() {
25485
+ return this.bookingGroup?.totalCollectedAtBooking ?? 0;
25486
+ }
25487
+ get bookingDue() {
25488
+ return Math.max(0, this.bookingTotal - this.bookingPaid);
25489
+ }
25490
+ loadBusinessSettings() {
25491
+ if (!this.businessId)
25492
+ return;
25493
+ this.restService.getBusinessAppointmentSettings(this.businessId).subscribe((res) => {
25494
+ this.businessSettings = res;
25495
+ }, () => {
25496
+ // Non-fatal - the review step just won't preview a home visit charge amount.
25497
+ });
25498
+ }
25469
25499
  ngOnInit() {
25470
25500
  // Login is required before entering the wizard at all (not mid-flow, like cart's
25471
25501
  // checkout-commit gate) - the wizard's selections live only in component memory, so a
@@ -25504,6 +25534,7 @@ class AppointmentBookingComponent extends BaseSection {
25504
25534
  // sets for this purpose.
25505
25535
  this.isAdminContext = localStorage.getItem("REQUEST_FROM") === 'ECOMMERCE';
25506
25536
  this.resetWizard();
25537
+ this.loadBusinessSettings();
25507
25538
  }
25508
25539
  // Restores the wizard to its start state - used for initial load (ngOnInit) and for "Book
25509
25540
  // Another" on the done screen, so a second booking doesn't inherit the previous one's
@@ -25958,14 +25989,20 @@ class AppointmentBookingComponent extends BaseSection {
25958
25989
  state: this.defaultAddress.stateName,
25959
25990
  zipCode: this.defaultAddress.zipCode,
25960
25991
  instructions: this.instructions
25961
- } : undefined
25992
+ } : undefined,
25993
+ // Skips online deposit collection server-side (see BookingGroupService#buildGroup) - a
25994
+ // staff-created booking can't complete a Cashfree checkout inline the way the live site
25995
+ // does, so it must never be routed through the payment gateway; any balance is collected
25996
+ // in person / recorded later via the invoice instead.
25997
+ adminBooking: this.isAdminBooking || this.isAdminContext,
25962
25998
  };
25999
+ const isAdmin = this.isAdminBooking || this.isAdminContext;
25963
26000
  this.restService.holdBooking(holdPayload).subscribe((group) => {
25964
26001
  this.bookingGroup = group;
25965
26002
  if (this.selectedMode !== 'STORE_VISIT' && this.productCartItems.length > 0) {
25966
26003
  this.bookingProductCartService.clear(this.selectedMode);
25967
26004
  }
25968
- if (group.status === 'HOLD' && group.totalCollectedAtBooking > 0) {
26005
+ if (!isAdmin && group.status === 'HOLD' && group.totalCollectedAtBooking > 0) {
25969
26006
  // Must act on this immediately - the hold expires in 10 minutes.
25970
26007
  this.restService.generatePaymentToken(group.groupId).subscribe((order) => {
25971
26008
  localStorage.setItem('appointmentPaymentId', order.pgOrderId);
@@ -25976,6 +26013,13 @@ class AppointmentBookingComponent extends BaseSection {
25976
26013
  this.messageService.add({ severity: 'error', summary: 'Payment Failed', detail: error.error?.message });
25977
26014
  });
25978
26015
  }
26016
+ else if (isAdmin && group.status === 'HOLD') {
26017
+ // Unexpected: the backend should have auto-confirmed this admin booking with zero
26018
+ // deposit. Surface an error rather than silently showing success for a booking that's
26019
+ // still expiring unconfirmed.
26020
+ this.isProcessing = false;
26021
+ this.messageService.add({ severity: 'error', summary: 'Booking Failed', detail: 'This booking requires a deposit and could not be auto-confirmed. Please try again or contact support.' });
26022
+ }
25979
26023
  else {
25980
26024
  this.apiStatus = true;
25981
26025
  this.selectedTab = 'statusTemplate';
@@ -26009,11 +26053,11 @@ class AppointmentBookingComponent extends BaseSection {
26009
26053
  this.resetWizard();
26010
26054
  }
26011
26055
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, deps: [{ token: RestService }, { token: EventsService }, { token: i2$2.Router }, { token: i6$1.MessageService }, { token: BookingProductCartService }, { token: StorageServiceService }, { token: i3$2.MatDialog }, { token: i3$2.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
26012
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", isAdminBooking: "isAdminBooking", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor", prefillContact: "prefillContact" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngIf=\"line.services.length\">\n <div class=\"summary-label\">Service(s)</div>\n <div class=\"summary-value\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.SlicePipe, name: "slice" }, { kind: "pipe", type: i3.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9$2.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i9.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
26056
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AppointmentBookingComponent, isStandalone: true, selector: "simpo-appointment-booking", inputs: { data: "data", index: "index", edit: "edit", isAdminBooking: "isAdminBooking", delete: "delete", customClass: "customClass", nextComponentColor: "nextComponentColor", prefillContact: "prefillContact" }, host: { listeners: { "window: resize": "getScreenSize($event)", "document:click": "closeOnOutsideClick()" } }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.SlicePipe, name: "slice" }, { kind: "pipe", type: i3.TitleCasePipe, name: "titlecase" }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i9$2.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i9.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatInputModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: LettersOnlyDirective, selector: "[simpoLettersOnly]" }, { kind: "directive", type: NumbersOnlyDirective, selector: "[simpoNumbersOnly]" }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
26013
26057
  }
26014
26058
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AppointmentBookingComponent, decorators: [{
26015
26059
  type: Component,
26016
- args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, MatDialogModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngIf=\"line.services.length\">\n <div class=\"summary-label\">Service(s)</div>\n <div class=\"summary-value\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"] }]
26060
+ args: [{ selector: 'simpo-appointment-booking', standalone: true, imports: [CdkDragPlaceholder, CommonModule, MatIcon, MatFormFieldModule, MatDatepickerModule, FormsModule, MatNativeDateModule, MatInputModule, MatDialogModule, LettersOnlyDirective, NumbersOnlyDirective, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_header\">\n <div class=\"header d-flex justify-content-between align-items-center\">\n <div class=\"back-btn d-flex justify-content-center align-items-center cursor-pointer gap-2 mb-3\"\n (click)=\"goBack()\">\n <mat-icon>keyboard_backspace</mat-icon><span *ngIf=\"screenWidth > 475\">Back to Home</span>\n </div>\n <div class=\"header-title\">\n <h1>Book New Appointment</h1>\n <p>{{businessName ?? \"N/A\" }}</p>\n </div>\n </div>\n\n <div class=\"progress-bar\">\n <div class=\"progress-fill\" [style.width]=\"barWidth + '%'\"></div>\n </div>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <ng-container *ngIf=\"selectedTab === 'modeSelection'\">\n <ng-container *ngTemplateOutlet=\"modeSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'serviceListing'\">\n <ng-container *ngIf=\"!skeletonLoader\">\n <ng-container *ngTemplateOutlet=\"serviceListing\"></ng-container>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'locationListing'\">\n <ng-container *ngTemplateOutlet=\"locationListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'staffListing'\">\n <ng-container *ngTemplateOutlet=\"staffListing\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab === 'dateSelection'\">\n <ng-container *ngTemplateOutlet=\"dateSelection\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='contactDetails'\">\n <ng-container *ngTemplateOutlet=\"contactDetails\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='paymentTab'\">\n <ng-container *ngTemplateOutlet=\"paymentTab\"></ng-container>\n </ng-container>\n <ng-container *ngIf=\"selectedTab==='statusTemplate'\">\n <ng-container *ngTemplateOutlet=\"statusTemplate\"></ng-container>\n </ng-container>\n </div>\n <div class=\"main_footer d-flex justify-content-center align-items-center\"\n *ngIf=\"selectedTab!=='statusTemplate' && selectedTab!=='modeSelection'\">\n <div class=\"footer-buttons\"\n [ngStyle]=\"{'justify-content': selectedTab != 'serviceListing' ? 'space-between' : 'end'}\">\n <span class=\"back-footer-btn cursor-pointer\" (click)=\"previousStep()\"\n *ngIf=\"selectedTab != 'serviceListing'\">Back</span>\n <button class=\"continue-btn\" [disabled]=\"!activeButton\" (click)=\"nextStep()\"\n *ngIf=\"selectedTab!='paymentTab'\">{{!loader ? 'Continue' : 'Loading...'}}</button>\n <button class=\"cursor-pointer d-flex justify-content-evenly align-items-center\"\n *ngIf=\"selectedTab==='paymentTab'\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\"\n [ngClass]=\"{'pay-now-btn' : bookingGroup?.totalCollectedAtBooking > 0 || !bookingGroup,'complete_booking' : bookingGroup && !bookingGroup?.totalCollectedAtBooking}\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/304012c1753440087996Background.png\">\n {{isProcessing ? 'Please wait...' : 'Confirm Booking'}}\n </button>\n </div>\n </div>\n</section>\n\n<ng-template #modeSelection>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>How would you like this?</h2>\n <p>Choose how you'd like to be served</p>\n <div class=\"services-grid\">\n <div class=\"service-card\" (click)=\"selectMode('STORE_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>storefront</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Visit our Store</div>\n </div>\n </div>\n <div class=\"service-description\">Come to us at one of our locations</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('HOME_VISIT')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>home</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">We come to you</div>\n </div>\n </div>\n <div class=\"service-description\">A professional visits your address</div>\n </div>\n <div class=\"service-card\" (click)=\"selectMode('VIDEO_CALL')\">\n <div class=\"service-header\">\n <div class=\"service-icon\"><mat-icon>videocam</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">Video consultation</div>\n </div>\n </div>\n <div class=\"service-description\">Connect over a video call</div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #serviceListing>\n <div class=\"w-60 service_section\">\n <div class=\"service-selection\">\n <h2>Select a Service</h2>\n <p>Choose the service(s) you'd like to book<span *ngIf=\"cartServices.length > 0\"> \u2014 {{cartServices.length}} selected</span></p>\n <p *ngIf=\"productCartItems.length > 0\" class=\"cart-hint\">{{productCartItems.length}} product(s) already in your cart \u2014 you can continue without picking a service.</p>\n\n <div class=\"services-grid\">\n <ng-container *ngFor=\"let service of serviceData\">\n <div class=\"\" (click)=\"selectService(service)\"\n [ngClass]=\"{ 'service-card-selected' : service?.selected, 'service-card': !service?.selected }\">\n <div class=\" service-header\">\n <div class=\"service-icon\"><mat-icon>person_outline</mat-icon></div>\n <div class=\"service-info\">\n <div class=\"service-title\">{{service?.name ? service?.name : 'N/A'}}</div>\n </div>\n <div>\n <div class=\"service-price\">\u20B9{{service?.priceDetails?.price ?\n service?.priceDetails?.price : 'N/A' }}</div>\n <div class=\"service-duration\">{{service?.duration ? service?.duration : 'N/A'}} min\n </div>\n </div>\n </div>\n <div class=\"service-description\" *ngIf=\"service?.description\">\n {{service?.description ? service?.description : 'N/A'}}\n </div>\n <div class=\"home-visit\" *ngIf=\"selectedMode === 'STORE_VISIT' && service?.homeAppointmentAvailable\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/982126c1758628863129furniture_16406103.png\">Home\n Visit Available</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #locationListing>\n <div class=\"location_section\">\n <div class=\"header flex-column align-items-start\">\n <h1>Choose Location</h1>\n <p>Select where you'd like to receive the service</p>\n </div>\n\n <div class=\"location-list\">\n <ng-container *ngFor=\"let location of locationData\">\n <div (click)=\"selectLocation(location)\"\n [ngClass]=\"{ 'location-card-selected' : location?.selected, 'location-card': !location?.selected }\">\n <div class=\"location-content\">\n <div class=\"location-info\">\n <div class=\"location-icon\"><img\n src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/427226c1758629157758store_3171510.png\">\n </div>\n <div class=\"location-details\">\n <div class=\"d-flex justify-content-between align-items-center\">\n <h3>{{location?.storeName ? location?.storeName : 'N/A'}}</h3>\n </div>\n <p>{{location?.addressDetails?.addressLine}}, {{location?.addressDetails?.city}},\n {{location?.addressDetails?.state}} {{location?.pincode}}</p>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</ng-template>\n\n<ng-template #staffListing>\n <div class=\"w-60 overflow-hidden staff-listing\">\n <div class=\"d-flex w-100 h-100\">\n <div class=\"w-100\">\n <div class=\"staff-header mb-3\">\n <h1>Select Staff Member</h1>\n <p class=\"staff-subtitle mb-0\">Choose your preferred professional</p>\n </div>\n\n <div class=\"search-container mb-4\">\n <div class=\"search-input-wrapper d-flex align-items-center\">\n <mat-icon class=\"search-icon me-2\">search</mat-icon>\n <input type=\"text\" class=\"search-input border-0 flex-grow-1\" placeholder=\"Search staff member by name...\" [(ngModel)]=\"staffSearchQuery\">\n <mat-icon class=\"clear-icon cursor-pointer ms-2\" *ngIf=\"staffSearchQuery\" (click)=\"staffSearchQuery = ''\">close</mat-icon>\n </div>\n </div>\n\n <!-- Pure product-only line: one flat staff list, same as the old single-service flow -->\n <div class=\"staff-list\" *ngIf=\"cartServices.length === 0\">\n <ng-container *ngFor=\"let staff of filteredStaff\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForProductOnlyLine(staff)\"\n [ngClass]=\"{ 'staff-card-selected' : staff?.selected, 'staff-card': !staff?.selected }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.staffName.slice(0,2).toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.staffName ? staff?.staffName : 'N/A') | titlecase}}</h3>\n <p class=\"staff-specialty\">{{(businessName && businessName !== 'N/A') ? businessName : 'Booking Specialist'}}</p>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"staff?.selected\">\n <mat-icon *ngIf=\"staff?.selected\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n\n <!-- Bundled cart: one pool per line that resolution couldn't collapse to a single provider -->\n <ng-container *ngIf=\"cartServices.length > 0\">\n <div class=\"staff-line-group mb-4\" *ngFor=\"let line of resolvedLines\">\n <ng-container *ngIf=\"line.candidateStaffPool?.length\">\n <h4 class=\"mb-2\">For {{line.services.length}} service(s): {{ (line.services | slice:0:3).length ? '' : '' }}<span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></h4>\n <div class=\"staff-list mb-3\">\n <ng-container *ngFor=\"let staff of line.candidateStaffPool\">\n <div class=\"card rounded-3 p-3\" (click)=\"selectStaffForLine(line, staff)\"\n [ngClass]=\"{ 'staff-card-selected' : line.selectedStaffId === staff.id, 'staff-card': line.selectedStaffId !== staff.id }\">\n <div class=\"d-flex align-items-center justify-content-between w-100\">\n <div class=\"d-flex align-items-center flex-grow-1\">\n <div class=\"staff-avatar rounded-circle d-flex align-items-center justify-content-center me-4\">\n {{staff?.name?.slice(0,2)?.toUpperCase()}}\n </div>\n <div class=\"staff-details flex-grow-1\">\n <h3 class=\"staff-name\">{{(staff?.name ? staff?.name : 'N/A') | titlecase}}</h3>\n </div>\n </div>\n <div class=\"selection-indicator\">\n <div class=\"checkmark-circle-mini d-flex align-items-center justify-content-center\" [class.selected]=\"line.selectedStaffId === staff.id\">\n <mat-icon *ngIf=\"line.selectedStaffId === staff.id\">check</mat-icon>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #dateSelection>\n <div class=\"w-60 date_section\">\n <div class=\"row justify-content-center h-100\">\n <div class=\"col-12 h-100\">\n <div class=\"datetime-header mb-2\">\n <h1>Select Date & Time</h1>\n <p class=\"datetime-subtitle mb-0\">Choose when you'd like your appointment</p>\n </div>\n\n <div class=\"d-flex gap-4 main_container\">\n <div [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\">\n <div class=\"section-card card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Select Date</h3>\n\n <div class=\"date-picker-container d-flex align-items-center justify-content-between\"\n (click)=\"$event.stopPropagation()\">\n <input type=\"text\" class=\"date-input border-0 rounded-2\" placeholder=\"dd-mm-yyyy\"\n [value]=\"selectedDateStr\" readonly (click)=\"toggleCalendar($event)\">\n\n <mat-icon class=\"ms-2\" (click)=\"toggleCalendar($event)\">calendar_today</mat-icon>\n </div>\n <div class=\"position-relative\" (click)=\"$event.stopPropagation()\">\n <div class=\"datepicker-popover\" *ngIf=\"showCalendar\">\n <mat-calendar [(selected)]=\"selectedDate\" [dateFilter]=\"dateFilter\"\n (selectedChange)=\"onDateSelected($event)\" class=\"datepicker-calendar\">\n </mat-calendar>\n </div>\n </div>\n </div>\n </div>\n\n <!-- One slot-picker per resolved line, side by side when there's more than one (design doc \u00A73b) -->\n <div class=\"time_selection\" [ngClass]=\"{'w-50' : screenWidth > 475 , 'w-100':screenWidth < 475}\" *ngIf=\"resolvedLines.length <= 1\">\n <div class=\"section-card card h-100 rounded-3 p-4\">\n <h3 class=\"section-title\">Available Times</h3>\n <div class=\"row g-2 mb-4 overflow-scroll\">\n <ng-container *ngIf=\"!skeletonLoader && resolvedLines[0]\">\n <div class=\"col-4\" *ngFor=\"let time of resolvedLines[0].slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(resolvedLines[0], time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Multi-line case: each line gets its own full-width card with a staff header -->\n <div class=\"d-flex gap-4 main_container flex-wrap\" *ngIf=\"resolvedLines.length > 1\">\n <div class=\"w-100\" *ngFor=\"let line of resolvedLines\">\n <div class=\"section-card card rounded-3 p-4\">\n <h3 class=\"section-title\">Professional: {{line.staffName || line.selectedStaffName}}</h3>\n <p class=\"mb-2\" *ngIf=\"line.services.length\"><span *ngFor=\"let s of line.services; let last = last\">{{s.name}}{{last ? '' : ', '}}</span></p>\n <div class=\"row g-2 mb-2 overflow-scroll\">\n <ng-container *ngIf=\"!line.slotsLoading\">\n <div class=\"col-4\" *ngFor=\"let time of line.slots\">\n <div class=\"time-slot rounded-2\" [class.selected]=\"time.selected\"\n (click)=\"selectSlotForLine(line, time)\">{{time ? time?.value : 'N/A'}}</div>\n </div>\n </ng-container>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #contactDetails>\n <div class=\"w-60 contact_section\">\n <div class=\"contact-header mb-2\">\n <h1>Contact Details</h1>\n <p class=\"contact-subtitle mb-0\">Provide your contact information</p>\n </div>\n\n <div class=\"d-flex gap-3 details_container flex-column w-100\">\n <div class=\"d-flex gap-4\">\n <div [ngClass]=\"{'w-50' : selectedMode === 'HOME_VISIT', 'w-100' : selectedMode !== 'HOME_VISIT'}\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Personal Information</h3>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Full Name\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"text\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.name\"\n (ngModelChange)=\"checkRequiredValues()\" simpoLettersOnly>\n </div>\n\n <div class=\"mb-4\">\n <label class=\"form-label d-flex align-items-center\">\n Email Address\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"email\" class=\"form-control form-input rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.email\"\n (ngModelChange)=\"checkRequiredValues()\"\n pattern=\"^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$\" #emailField=\"ngModel\"\n name=\"email\" required>\n </div>\n\n <div class=\"mb-0\">\n <label class=\"form-label d-flex align-items-center\">\n Phone Number\n <span class=\"required-asterisk\">*</span>\n </label>\n <input type=\"tel\" class=\"form-control rounded-2\"\n [(ngModel)]=\"appointmentPayload.customerDetail.phoneNumber\"\n (ngModelChange)=\"checkRequiredValues()\" simpoNumbersOnly\n [ngClass]=\"{'mobile_number' : appointmentPayload.customerDetail.phoneNumber.length != 10}\">\n </div>\n </div>\n </div>\n <!-- Home Visit address. Customer context: same saved-address flow as\n checkout/BookAppointmentComponent. Admin context (isAdminBooking): no\n logged-in customer account to read a saved address book from, so staff type\n the address manually instead. -->\n <div class=\"w-50\" *ngIf=\"selectedMode === 'HOME_VISIT'\">\n <div class=\"form-section card rounded-3 p-4 h-100\">\n <h3 class=\"section-title\">Home Visit Details</h3>\n\n <ng-container *ngIf=\"!isAdminBooking; else manualHomeVisitAddress\">\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n </ng-container>\n\n <ng-template #manualHomeVisitAddress>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Name</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.receiverName\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Receiver Phone</label>\n <input type=\"tel\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.receiverPhone\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 1</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine1\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Address Line 2 (optional)</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.addressLine2\">\n </div>\n <div class=\"d-flex gap-2 mb-3\">\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">City</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.city\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n <div class=\"w-50\">\n <label class=\"form-label d-flex align-items-center\">State</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" [(ngModel)]=\"homeVisitAddress.state\">\n </div>\n </div>\n <div class=\"mb-3\">\n <label class=\"form-label d-flex align-items-center\">Pincode</label>\n <input type=\"text\" class=\"form-control form-input rounded-2\" simpoNumbersOnly [(ngModel)]=\"homeVisitAddress.zipCode\" (ngModelChange)=\"checkRequiredValues()\">\n </div>\n </ng-template>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Special Instructions</label>\n <textarea class=\"form-control form-textarea rounded-2\"\n placeholder=\"Any special instructions for the professional (optional)\"\n [(ngModel)]=\"instructions\"></textarea>\n </div>\n </div>\n </div>\n </div>\n <div class=\"policies-container\"\n *ngIf=\"cartServices[0]?.cancellationPolicy?.length > 0 || cartServices[0]?.reschedulePolicy?.length\">\n <h2 class=\"policies-title\">Policies & Terms</h2>\n\n <div class=\"policy-items-container d-flex flex-column gap-3\">\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showCancellationPolicy = !showCancellationPolicy\">\n <h3 class=\"policy-title\">Cancellation Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showCancellationPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showCancellationPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showCancellationPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.cancellationPolicy\">&#8226;\n {{policy}}</span>\n </div>\n\n <div class=\"policy-item d-flex justify-content-between align-items-center\"\n (click)=\"showReducingPolicy = !showReducingPolicy\">\n <h3 class=\"policy-title\">Rescheduling Policy</h3>\n <div class=\"policy-arrow d-flex align-items-center justify-content-center\"><mat-icon\n *ngIf=\"!showReducingPolicy\">keyboard_arrow_right</mat-icon>\n <mat-icon *ngIf=\"showReducingPolicy\">keyboard_arrow_down</mat-icon>\n </div>\n </div>\n <div class=\"cancellation_policies d-flex flex-column gap-2 fw-500\"\n *ngIf=\"showReducingPolicy\">\n <span *ngFor=\"let policy of cartServices[0]?.reschedulePolicy\">&#8226; {{policy}}</span>\n </div>\n </div>\n\n <div class=\"acceptance-section\">\n <input type=\"checkbox\" class=\"custom-checkbox\" [(ngModel)]=\"termsAndConditions\"\n (ngModelChange)=\"checkRequiredValues()\">\n <p class=\"acceptance-text\" style=\"margin-bottom:0px !important\">\n I understand and accept the cancellation & rescheduling policies.\n </p>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #paymentTab>\n <div class=\"w-60 payment_section\">\n <div class=\"w-100 h-100\">\n <div class=\"w-100 d-flex justify-content-center align-items-center flex-column\">\n <div class=\"payment-header mb-3 w-100\">\n <h1 style=\"font-size:24px;font-weight: 600;\">Booking Summary</h1>\n <p class=\"payment-subtitle mb-0\">Review your booking before confirming</p>\n </div>\n\n <div class=\"booking-summary-card\" [ngClass]=\"{'w-100' : screenWidth < 475,'w-50':screenWidth > 475}\">\n <div *ngFor=\"let line of resolvedLines; let i = index\">\n <h2 class=\"summary-title\" *ngIf=\"resolvedLines.length > 1\">Line {{i + 1}}</h2>\n <div class=\"summary-row\" *ngFor=\"let s of line.services\">\n <div class=\"summary-label\">{{s.name}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{servicePrice(s.id)}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"line.staffName || line.selectedStaffName\">\n <div class=\"summary-label\">Professional</div>\n <div class=\"summary-value\">{{line.staffName || line.selectedStaffName}}</div>\n </div>\n <div class=\"summary-row\" *ngIf=\"selectedMode === 'STORE_VISIT'\">\n <div class=\"summary-label\">Location</div>\n <div class=\"summary-value\">{{selectedLocation?.storeName ?? 'N/A'}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Date & Time</div>\n <div class=\"summary-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</div>\n </div>\n </div>\n\n <div *ngIf=\"productCartItems.length > 0\">\n <h2 class=\"summary-title\">Products</h2>\n <div class=\"summary-row\" *ngFor=\"let p of productCartItems\">\n <div class=\"summary-label\">{{p.itemName}} x{{p.quantity}}</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{(p.sellingPrice ?? p.price ?? 0) * (p.quantity ?? 1)}}</div>\n </div>\n </div>\n\n <h2 class=\"summary-title\">Payment</h2>\n <div class=\"summary-row\" *ngIf=\"homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{homeVisitCharge}}</div>\n </div>\n <div class=\"summary-row\">\n <div class=\"summary-label\">Total</div>\n <div class=\"summary-value\"><span class=\"currency-symbol\">\u20B9</span>{{reviewTotal}}</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #statusTemplate>\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book you appointment. Please\n try again later'}}\n </p>\n\n <!-- Video Call link, when already present on the confirmed group (a paid Video Call's\n link only appears once payment verification completes, handled elsewhere - see\n verify-payment.component.ts, not this screen). -->\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && selectedMode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\" *ngFor=\"let line of resolvedLines\">\n <span class=\"detail-label\">{{line.services.length ? (line.services[0].name) : 'Products'}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{line.selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"bookingGroup?.homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{bookingGroup.homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <ng-container *ngIf=\"!isAdminContext; else adminDoneActions\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </ng-container>\n <ng-template #adminDoneActions>\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToAppointmentsList()\">Back to Appointments List</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"bookAnother()\">Book Another</button>\n </ng-template>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.date-picker-container{border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;display:flex;align-items:center;justify-content:space-between;transition:var(--transition-smooth);background-color:var(--slate-50);cursor:pointer}.date-picker-container:hover{border-color:var(--slate-400);background-color:#fff}.date-input{font-size:.95rem;font-weight:600;color:var(--slate-800)!important;background:transparent;border:none;outline:none;cursor:pointer;width:100%}.date-picker-container mat-icon{color:var(--color-primary)!important;font-size:20px!important;width:20px!important;height:20px!important}.datepicker-popover{position:absolute;z-index:1000;margin-top:4px;border-radius:var(--border-radius-lg);overflow:hidden;box-shadow:var(--shadow-xl);background:#fff;border:1px solid var(--slate-200);width:320px}::ng-deep .datepicker-calendar{border-radius:var(--border-radius-lg)!important;width:100%!important}::ng-deep .mat-calendar-header{background:var(--color-accent-gradient)!important;color:#fff!important;padding:.5rem!important}::ng-deep .mat-calendar-content{padding:8px!important}::ng-deep .mat-calendar-controls{margin:0!important}::ng-deep .mat-calendar-period-button{color:#fff!important;font-weight:700!important;font-size:1rem!important}::ng-deep .mat-calendar-arrow{fill:#fff!important}::ng-deep .mat-calendar-previous-button,::ng-deep .mat-calendar-next-button{color:#fff!important}::ng-deep .mat-calendar-body-cell{font-size:13px!important}::ng-deep .mat-calendar-body-cell-content{font-weight:600!important;color:var(--slate-800)!important;border-radius:8px!important}::ng-deep .mat-calendar-body-selected{background:var(--color-accent-gradient)!important;color:#fff!important;box-shadow:0 4px 10px #23086033!important}::ng-deep .mat-calendar-body-today:not(.mat-calendar-body-selected){border:2px solid var(--color-primary)!important;color:var(--color-primary)!important}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.9rem;font-weight:600;color:var(--slate-800)!important;padding:.75rem .5rem;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.main_footer{border-top:1px solid var(--slate-200);background-color:#fff;padding:15px;flex-shrink:0;display:flex;justify-content:center;box-shadow:0 -4px 12px #00000005}.footer-buttons{width:100%;max-width:800px;display:flex;align-items:center}.back-footer-btn{font-size:.95rem;font-weight:600;color:var(--slate-600)!important;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);cursor:pointer}.back-footer-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.complete_booking,.pay-now-btn{background:var(--color-accent-gradient)!important;color:#fff!important;border:none;padding:.75rem 2.25rem!important;font-size:.95rem!important;font-weight:600;border-radius:var(--border-radius-md)!important;box-shadow:0 4px 12px #23086040;transition:var(--transition-smooth);cursor:pointer;display:flex;align-items:center;gap:.5rem;width:max-content!important}.complete_booking img,.pay-now-btn img{width:20px;height:20px;filter:brightness(0) invert(1)}.complete_booking:hover:not([disabled]),.pay-now-btn:hover:not([disabled]){transform:translateY(-2px);box-shadow:0 6px 18px #23086059}.complete_booking:disabled,.pay-now-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed;box-shadow:none}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.datepicker-popover{width:100%;left:0}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}h1{font-size:24px!important;font-weight:600!important}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}\n"] }]
26017
26061
  }], ctorParameters: () => [{ type: RestService }, { type: EventsService }, { type: i2$2.Router }, { type: i6$1.MessageService }, { type: BookingProductCartService }, { type: StorageServiceService }, { type: i3$2.MatDialog }, { type: i3$2.MatDialogRef, decorators: [{
26018
26062
  type: Optional
26019
26063
  }] }], propDecorators: { data: [{
@@ -26161,6 +26205,15 @@ class BookAppointmentComponent extends BaseSection {
26161
26205
  get homeVisitCharge() {
26162
26206
  return this.businessSettings?.homeVisitCharge ?? 0;
26163
26207
  }
26208
+ get bookingTotal() {
26209
+ return (this.bookingGroup?.totalPayable ?? 0) + (this.bookingGroup?.homeVisitCharge ?? 0);
26210
+ }
26211
+ get bookingPaid() {
26212
+ return this.bookingGroup?.totalCollectedAtBooking ?? 0;
26213
+ }
26214
+ get bookingDue() {
26215
+ return Math.max(0, this.bookingTotal - this.bookingPaid);
26216
+ }
26164
26217
  ngOnInit() {
26165
26218
  this.screenWidth = window.innerWidth;
26166
26219
  this.route.queryParams.subscribe((params) => {
@@ -26427,11 +26480,11 @@ class BookAppointmentComponent extends BaseSection {
26427
26480
  });
26428
26481
  }
26429
26482
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookAppointmentComponent, deps: [{ token: i2$2.ActivatedRoute }, { token: i2$2.Router }, { token: RestService }, { token: EventsService }, { token: i6$1.MessageService }, { token: StorageServiceService }, { token: BookingProductCartService }, { token: i3$2.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
26430
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BookAppointmentComponent, isStandalone: true, selector: "simpo-book-appointment", inputs: { data: "data", index: "index", edit: "edit", delete: "delete", customClass: "customClass" }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <div class=\"wiz-container\">\n\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"single-grid\">\n <div class=\"single-left\">\n\n <div class=\"wizard-banner\" [id]=\"data?.id\" [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div class=\"wizard-banner-title\">{{bannerTitle}}</div>\n <div class=\"wizard-banner-desc\">{{bannerDesc}}</div>\n </div>\n\n <div class=\"sub-step-tabs\">\n <button type=\"button\" class=\"sub-step-tab\" *ngFor=\"let s of subSteps; trackBy: trackBySubStepKey\"\n [class.active]=\"s.active\" [class.locked]=\"s.locked\" [disabled]=\"s.locked\" (click)=\"s.go()\">\n <span class=\"sub-step-dot\">{{s.num}}</span>\n {{s.label}}\n </button>\n </div>\n\n <div class=\"sub-step-content\">\n <ng-container *ngIf=\"subStep === 'date'\">\n <div class=\"section-card card\">\n <div class=\"week-header\">\n <div>\n <h3 class=\"section-title mb-0\">Select a Date</h3>\n <p class=\"subtitle mb-0\">{{weekRangeLabel}}</p>\n </div>\n <div class=\"week-arrows\">\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"prevWeek()\" [disabled]=\"weekOffset <= 0\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"nextWeek()\" [disabled]=\"weekOffset >= maxWeekOffset\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"week-strip\">\n <button type=\"button\" class=\"week-day\" *ngFor=\"let d of weekDays\" [class.selected]=\"d.selected\"\n (click)=\"pickDay(d)\">\n <div class=\"week-day-dow\">{{d.dow}}</div>\n <div class=\"week-day-num\">{{d.num}}</div>\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'time'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title mb-0\">Select a Time</h3>\n <p class=\"subtitle\" *ngIf=\"selectedDateStr\">Available slots for {{selectedDateStr}}</p>\n <p class=\"subtitle mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n <div class=\"time-slot-grid overflow-scroll\" *ngIf=\"selectedDateStr\">\n <ng-container *ngIf=\"!slotsLoading; else slotsLoadingTpl\">\n <div class=\"time-slot rounded-2\" *ngFor=\"let time of slots\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time?.value}}</div>\n <p class=\"mb-0\" *ngIf=\"slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n <ng-template #slotsLoadingTpl>\n <p class=\"mb-0\">Loading available times...</p>\n </ng-template>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'details'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title\">Booking Details</h3>\n <div class=\"booking-for-line\">\n Booking for <strong>{{userDetails?.contact?.name}}</strong>\n <ng-container *ngIf=\"userDetails?.contact?.mobile\"> \u00B7 {{userDetails?.contact?.mobile}}</ng-container>\n <ng-container *ngIf=\"userDetails?.contact?.email\"> \u00B7 {{userDetails?.contact?.email}}</ng-container>\n </div>\n\n <ng-container *ngIf=\"mode === 'HOME_VISIT'\">\n <p class=\"policies-title mt-3 mb-2\" style=\"font-size:1rem;\">Shipping Address</p>\n\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Instructions (optional)</label>\n <textarea class=\"form-control form-textarea rounded-2\" [(ngModel)]=\"instructions\"></textarea>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div class=\"sub-step-footer\">\n <button type=\"button\" class=\"sub-back-btn\" [disabled]=\"subBackOff\" (click)=\"subBack()\">Back</button>\n <div class=\"sub-chosen-label\">{{subChosenLabel}}</div>\n <button type=\"button\" class=\"sub-next-btn\" *ngIf=\"subStep !== 'details'\" [disabled]=\"subNextOff\" (click)=\"subNext()\">Next</button>\n </div>\n </div>\n\n <div class=\"single-right section-card card\">\n <h3 class=\"section-title\">Your Shortlisted Designs</h3>\n <div class=\"design-row\" *ngFor=\"let it of productCartItems\">\n <div class=\"design-thumb\"></div>\n <div class=\"design-info\">\n <div class=\"design-name\">{{it.itemName}}</div>\n <div class=\"design-price\">\u20B9{{(it.sellingPrice ?? it.price ?? 0) * (it.quantity ?? 1)}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"add-more-btn\" (click)=\"goToListing()\">+ Add More Designs</button>\n\n <div class=\"summary-divider\"></div>\n\n <div class=\"summary-line\" *ngIf=\"mode !== 'HOME_VISIT' || homeVisitCharge <= 0\">\n <div class=\"summary-label\">Service:</div>\n <div class=\"free-label\">FREE</div>\n </div>\n <div class=\"summary-line\" *ngIf=\"mode === 'HOME_VISIT' && homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\">\u20B9{{homeVisitCharge}}</div>\n </div>\n\n <button class=\"continue-btn w-100 mt-2\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review Booking</button>\n <p class=\"footnote\">You will review everything on the next screen before it is confirmed.</p>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"review-wrap\">\n <div class=\"review-card card\">\n <div class=\"review-header\">Review your booking</div>\n <div class=\"review-row\" *ngFor=\"let rc of reviewRows\">\n <div class=\"review-k\">{{rc.k}}</div>\n <div class=\"review-v\">{{rc.v}}</div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button type=\"button\" class=\"review-back-btn\" (click)=\"backToForm()\">Back &amp; edit</button>\n <button type=\"button\" class=\"review-confirm-btn\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\">\n {{isProcessing ? 'Please wait...' : (mode === 'HOME_VISIT' ? 'Confirm Home Visit' : 'Confirm Video Call')}}\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.75rem;font-weight:600;color:var(--slate-800)!important;height:34px;padding:0 4px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}.wiz-container{width:100%;max-width:1120px}.wizard-banner{border-radius:var(--border-radius-lg);padding:1.125rem 1.5rem;background:var(--color-accent-gradient);box-shadow:var(--shadow-sm)}.wizard-banner-title{font-size:1.1rem;font-weight:700;color:#fff!important}.wizard-banner-desc{font-size:.85rem;line-height:1.5;color:#ffffffd9!important;padding-top:.2rem;max-width:520px}.sub-step-tabs{display:flex;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.sub-step-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;border:none;background:#fff;padding:.85rem 0;font-size:.85rem;font-weight:600;color:var(--slate-500)!important;cursor:pointer;border-bottom:2px solid transparent;transition:var(--transition-smooth)}.sub-step-tab.active{color:var(--slate-900)!important;border-bottom-color:var(--color-primary);background:var(--slate-50)}.sub-step-tab.locked{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-dot{width:20px;height:20px;border-radius:50%;background:var(--slate-200);color:var(--slate-500)!important;font-size:.7rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.sub-step-tab.active .sub-step-dot{background:var(--color-accent-gradient);color:#fff!important}.sub-step-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.85rem 1.25rem;box-shadow:var(--shadow-sm)}.sub-step-footer .sub-back-btn{width:auto;flex:0 0 auto;height:40px;font-size:.85rem;font-weight:600;color:var(--slate-600)!important;background:none;border:1.5px solid var(--slate-200);padding:0 18px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-back-btn:hover:not(:disabled){color:var(--slate-900)!important;background-color:var(--slate-100)}.sub-step-footer .sub-back-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-footer .sub-chosen-label{width:auto;flex:1 1 auto;font-size:.8rem;color:var(--slate-500)!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;text-align:center}.sub-step-footer .sub-next-btn{width:auto;flex:0 0 auto;height:40px;background:var(--color-accent-gradient);color:#fff!important;border:none;padding:0 22px;border-radius:var(--border-radius-md);font-size:.85rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-next-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.sub-step-footer .sub-next-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.single-grid{display:grid;grid-template-columns:1fr 360px;gap:1.5rem;align-items:start}.single-left{display:flex;flex-direction:column;gap:1.5rem}.single-right{align-self:flex-start;position:sticky;top:10px}.week-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:14px}.week-arrows{display:flex;gap:8px}.week-arrow-btn{width:34px;height:34px;border-radius:8px;border:1px solid var(--slate-200);background:#fff;color:var(--slate-700)!important;cursor:pointer;display:flex;align-items:center;justify-content:center}.week-arrow-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.week-strip{display:grid;grid-template-columns:repeat(7,1fr);gap:10px}.week-day{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem .25rem;cursor:pointer;transition:var(--transition-smooth);text-align:center}.week-day:hover{border-color:var(--slate-400)}.week-day.selected{background:var(--color-accent-gradient);border-color:transparent}.week-day.selected .week-day-dow,.week-day.selected .week-day-num{color:#fff!important}.week-day-dow{font-size:.75rem;font-weight:600;color:var(--slate-500)!important;text-transform:uppercase}.week-day-num{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-top:2px}.booking-for-line{font-size:.9rem;color:var(--slate-600)!important;padding:.85rem 1rem;background:var(--slate-50);border-radius:var(--border-radius-md);margin-bottom:.5rem}.booking-for-line strong{color:var(--slate-900)!important}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.design-row{display:flex;gap:13px;align-items:center;padding-bottom:1rem}.design-thumb{width:56px;height:56px;border-radius:8px;background:var(--slate-100);flex:none}.design-info{flex:1}.design-name{font-size:13.5px;color:var(--slate-900)!important;line-height:1.35}.design-price{font-size:13.5px;font-weight:600;color:var(--slate-900)!important;margin-top:3px}.add-more-btn{width:100%;height:44px;border:1.5px dashed var(--slate-300);border-radius:8px;background:none;color:var(--color-primary)!important;font-size:13px;font-weight:600;cursor:pointer;margin-bottom:1rem}.summary-divider{height:1px;background:var(--slate-100);margin-bottom:1rem}.summary-line{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.free-label{font-size:13.5px;font-weight:600;color:var(--color-success)!important}.footnote{font-size:11.5px;line-height:1.5;color:var(--slate-500)!important;text-align:center;margin:.75rem 0 0}.review-wrap{max-width:560px;margin:0 auto;display:flex;flex-direction:column;gap:16px}.review-card{border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.review-actions{display:flex;gap:12px}.review-actions .review-back-btn{flex:1;height:48px;border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);background:#fff;color:var(--slate-600)!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-back-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.review-actions .review-confirm-btn{flex:1;height:48px;border:none;border-radius:var(--border-radius-md);background:var(--color-accent-gradient);color:#fff!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-confirm-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.review-actions .review-confirm-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.review-header{padding:14px 18px;background:var(--slate-50);border-bottom:1px solid var(--slate-100);font-size:14.5px;font-weight:700;color:var(--slate-900)!important}.review-row{display:flex;justify-content:space-between;gap:16px;padding:12px 18px;border-bottom:1px solid var(--slate-100);font-size:13.5px}.review-row:last-child{border-bottom:none}.review-k{color:var(--slate-500)!important;flex-shrink:0}.review-v{color:var(--slate-900)!important;font-weight:500;text-align:right}@media screen and (max-width: 900px){.single-grid{grid-template-columns:1fr}.single-right{position:static}}@media screen and (max-width: 475px){.week-strip{gap:6px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
26483
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BookAppointmentComponent, isStandalone: true, selector: "simpo-book-appointment", inputs: { data: "data", index: "index", edit: "edit", delete: "delete", customClass: "customClass" }, providers: [MessageService], usesInheritance: true, ngImport: i0, template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <div class=\"wiz-container\">\n\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"single-grid\">\n <div class=\"single-left\">\n\n <div class=\"wizard-banner\" [id]=\"data?.id\" [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div class=\"wizard-banner-title\">{{bannerTitle}}</div>\n <div class=\"wizard-banner-desc\">{{bannerDesc}}</div>\n </div>\n\n <div class=\"sub-step-tabs\">\n <button type=\"button\" class=\"sub-step-tab\" *ngFor=\"let s of subSteps; trackBy: trackBySubStepKey\"\n [class.active]=\"s.active\" [class.locked]=\"s.locked\" [disabled]=\"s.locked\" (click)=\"s.go()\">\n <span class=\"sub-step-dot\">{{s.num}}</span>\n {{s.label}}\n </button>\n </div>\n\n <div class=\"sub-step-content\">\n <ng-container *ngIf=\"subStep === 'date'\">\n <div class=\"section-card card\">\n <div class=\"week-header\">\n <div>\n <h3 class=\"section-title mb-0\">Select a Date</h3>\n <p class=\"subtitle mb-0\">{{weekRangeLabel}}</p>\n </div>\n <div class=\"week-arrows\">\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"prevWeek()\" [disabled]=\"weekOffset <= 0\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"nextWeek()\" [disabled]=\"weekOffset >= maxWeekOffset\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"week-strip\">\n <button type=\"button\" class=\"week-day\" *ngFor=\"let d of weekDays\" [class.selected]=\"d.selected\"\n (click)=\"pickDay(d)\">\n <div class=\"week-day-dow\">{{d.dow}}</div>\n <div class=\"week-day-num\">{{d.num}}</div>\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'time'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title mb-0\">Select a Time</h3>\n <p class=\"subtitle\" *ngIf=\"selectedDateStr\">Available slots for {{selectedDateStr}}</p>\n <p class=\"subtitle mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n <div class=\"time-slot-grid overflow-scroll\" *ngIf=\"selectedDateStr\">\n <ng-container *ngIf=\"!slotsLoading; else slotsLoadingTpl\">\n <div class=\"time-slot rounded-2\" *ngFor=\"let time of slots\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time?.value}}</div>\n <p class=\"mb-0\" *ngIf=\"slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n <ng-template #slotsLoadingTpl>\n <p class=\"mb-0\">Loading available times...</p>\n </ng-template>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'details'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title\">Booking Details</h3>\n <div class=\"booking-for-line\">\n Booking for <strong>{{userDetails?.contact?.name}}</strong>\n <ng-container *ngIf=\"userDetails?.contact?.mobile\"> \u00B7 {{userDetails?.contact?.mobile}}</ng-container>\n <ng-container *ngIf=\"userDetails?.contact?.email\"> \u00B7 {{userDetails?.contact?.email}}</ng-container>\n </div>\n\n <ng-container *ngIf=\"mode === 'HOME_VISIT'\">\n <p class=\"policies-title mt-3 mb-2\" style=\"font-size:1rem;\">Shipping Address</p>\n\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Instructions (optional)</label>\n <textarea class=\"form-control form-textarea rounded-2\" [(ngModel)]=\"instructions\"></textarea>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div class=\"sub-step-footer\">\n <button type=\"button\" class=\"sub-back-btn\" [disabled]=\"subBackOff\" (click)=\"subBack()\">Back</button>\n <div class=\"sub-chosen-label\">{{subChosenLabel}}</div>\n <button type=\"button\" class=\"sub-next-btn\" *ngIf=\"subStep !== 'details'\" [disabled]=\"subNextOff\" (click)=\"subNext()\">Next</button>\n </div>\n </div>\n\n <div class=\"single-right section-card card\">\n <h3 class=\"section-title\">Your Shortlisted Designs</h3>\n <div class=\"design-row\" *ngFor=\"let it of productCartItems\">\n <div class=\"design-thumb\"></div>\n <div class=\"design-info\">\n <div class=\"design-name\">{{it.itemName}}</div>\n <div class=\"design-price\">\u20B9{{(it.sellingPrice ?? it.price ?? 0) * (it.quantity ?? 1)}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"add-more-btn\" (click)=\"goToListing()\">+ Add More Designs</button>\n\n <div class=\"summary-divider\"></div>\n\n <div class=\"summary-line\" *ngIf=\"mode !== 'HOME_VISIT' || homeVisitCharge <= 0\">\n <div class=\"summary-label\">Service:</div>\n <div class=\"free-label\">FREE</div>\n </div>\n <div class=\"summary-line\" *ngIf=\"mode === 'HOME_VISIT' && homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\">\u20B9{{homeVisitCharge}}</div>\n </div>\n\n <button class=\"continue-btn w-100 mt-2\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review Booking</button>\n <p class=\"footnote\">You will review everything on the next screen before it is confirmed.</p>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"review-wrap\">\n <div class=\"review-card card\">\n <div class=\"review-header\">Review your booking</div>\n <div class=\"review-row\" *ngFor=\"let rc of reviewRows\">\n <div class=\"review-k\">{{rc.k}}</div>\n <div class=\"review-v\">{{rc.v}}</div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button type=\"button\" class=\"review-back-btn\" (click)=\"backToForm()\">Back &amp; edit</button>\n <button type=\"button\" class=\"review-confirm-btn\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\">\n {{isProcessing ? 'Please wait...' : (mode === 'HOME_VISIT' ? 'Confirm Home Visit' : 'Confirm Video Call')}}\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.75rem;font-weight:600;color:var(--slate-800)!important;height:34px;padding:0 4px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}.wiz-container{width:100%;max-width:1120px}.wizard-banner{border-radius:var(--border-radius-lg);padding:1.125rem 1.5rem;background:var(--color-accent-gradient);box-shadow:var(--shadow-sm)}.wizard-banner-title{font-size:1.1rem;font-weight:700;color:#fff!important}.wizard-banner-desc{font-size:.85rem;line-height:1.5;color:#ffffffd9!important;padding-top:.2rem;max-width:520px}.sub-step-tabs{display:flex;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.sub-step-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;border:none;background:#fff;padding:.85rem 0;font-size:.85rem;font-weight:600;color:var(--slate-500)!important;cursor:pointer;border-bottom:2px solid transparent;transition:var(--transition-smooth)}.sub-step-tab.active{color:var(--slate-900)!important;border-bottom-color:var(--color-primary);background:var(--slate-50)}.sub-step-tab.locked{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-dot{width:20px;height:20px;border-radius:50%;background:var(--slate-200);color:var(--slate-500)!important;font-size:.7rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.sub-step-tab.active .sub-step-dot{background:var(--color-accent-gradient);color:#fff!important}.sub-step-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.85rem 1.25rem;box-shadow:var(--shadow-sm)}.sub-step-footer .sub-back-btn{width:auto;flex:0 0 auto;height:40px;font-size:.85rem;font-weight:600;color:var(--slate-600)!important;background:none;border:1.5px solid var(--slate-200);padding:0 18px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-back-btn:hover:not(:disabled){color:var(--slate-900)!important;background-color:var(--slate-100)}.sub-step-footer .sub-back-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-footer .sub-chosen-label{width:auto;flex:1 1 auto;font-size:.8rem;color:var(--slate-500)!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;text-align:center}.sub-step-footer .sub-next-btn{width:auto;flex:0 0 auto;height:40px;background:var(--color-accent-gradient);color:#fff!important;border:none;padding:0 22px;border-radius:var(--border-radius-md);font-size:.85rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-next-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.sub-step-footer .sub-next-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.single-grid{display:grid;grid-template-columns:1fr 360px;gap:1.5rem;align-items:start}.single-left{display:flex;flex-direction:column;gap:1.5rem}.single-right{align-self:flex-start;position:sticky;top:10px}.week-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:14px}.week-arrows{display:flex;gap:8px}.week-arrow-btn{width:34px;height:34px;border-radius:8px;border:1px solid var(--slate-200);background:#fff;color:var(--slate-700)!important;cursor:pointer;display:flex;align-items:center;justify-content:center}.week-arrow-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.week-strip{display:grid;grid-template-columns:repeat(7,1fr);gap:10px}.week-day{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem .25rem;cursor:pointer;transition:var(--transition-smooth);text-align:center}.week-day:hover{border-color:var(--slate-400)}.week-day.selected{background:var(--color-accent-gradient);border-color:transparent}.week-day.selected .week-day-dow,.week-day.selected .week-day-num{color:#fff!important}.week-day-dow{font-size:.75rem;font-weight:600;color:var(--slate-500)!important;text-transform:uppercase}.week-day-num{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-top:2px}.booking-for-line{font-size:.9rem;color:var(--slate-600)!important;padding:.85rem 1rem;background:var(--slate-50);border-radius:var(--border-radius-md);margin-bottom:.5rem}.booking-for-line strong{color:var(--slate-900)!important}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.design-row{display:flex;gap:13px;align-items:center;padding-bottom:1rem}.design-thumb{width:56px;height:56px;border-radius:8px;background:var(--slate-100);flex:none}.design-info{flex:1}.design-name{font-size:13.5px;color:var(--slate-900)!important;line-height:1.35}.design-price{font-size:13.5px;font-weight:600;color:var(--slate-900)!important;margin-top:3px}.add-more-btn{width:100%;height:44px;border:1.5px dashed var(--slate-300);border-radius:8px;background:none;color:var(--color-primary)!important;font-size:13px;font-weight:600;cursor:pointer;margin-bottom:1rem}.summary-divider{height:1px;background:var(--slate-100);margin-bottom:1rem}.summary-line{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.free-label{font-size:13.5px;font-weight:600;color:var(--color-success)!important}.footnote{font-size:11.5px;line-height:1.5;color:var(--slate-500)!important;text-align:center;margin:.75rem 0 0}.review-wrap{max-width:560px;margin:0 auto;display:flex;flex-direction:column;gap:16px}.review-card{border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.review-actions{display:flex;gap:12px}.review-actions .review-back-btn{flex:1;height:48px;border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);background:#fff;color:var(--slate-600)!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-back-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.review-actions .review-confirm-btn{flex:1;height:48px;border:none;border-radius:var(--border-radius-md);background:var(--color-accent-gradient);color:#fff!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-confirm-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.review-actions .review-confirm-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.review-header{padding:14px 18px;background:var(--slate-50);border-bottom:1px solid var(--slate-100);font-size:14.5px;font-weight:700;color:var(--slate-900)!important}.review-row{display:flex;justify-content:space-between;gap:16px;padding:12px 18px;border-bottom:1px solid var(--slate-100);font-size:13.5px}.review-row:last-child{border-bottom:none}.review-k{color:var(--slate-500)!important;flex-shrink:0}.review-v{color:var(--slate-900)!important;font-weight:500;text-align:right}@media screen and (max-width: 900px){.single-grid{grid-template-columns:1fr}.single-right{position:static}}@media screen and (max-width: 475px){.week-strip{gap:6px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i9.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i9.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i9.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i11.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "directive", type: HoverDirective, selector: "[simpoHover]", outputs: ["hovering"] }, { kind: "component", type: HoverElementsComponent, selector: "simpo-hover-elements", inputs: ["data", "index", "editOptions", "isMerged", "isEcommerce"], outputs: ["edit"] }, { kind: "directive", type: BackgroundDirective, selector: "[simpoBackground]", inputs: ["simpoBackground", "scrollValue"] }] }); }
26431
26484
  }
26432
26485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BookAppointmentComponent, decorators: [{
26433
26486
  type: Component,
26434
- args: [{ selector: 'simpo-book-appointment', standalone: true, imports: [CommonModule, MatIcon, MatIconModule, FormsModule, MatDialogModule, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <div class=\"wiz-container\">\n\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"single-grid\">\n <div class=\"single-left\">\n\n <div class=\"wizard-banner\" [id]=\"data?.id\" [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div class=\"wizard-banner-title\">{{bannerTitle}}</div>\n <div class=\"wizard-banner-desc\">{{bannerDesc}}</div>\n </div>\n\n <div class=\"sub-step-tabs\">\n <button type=\"button\" class=\"sub-step-tab\" *ngFor=\"let s of subSteps; trackBy: trackBySubStepKey\"\n [class.active]=\"s.active\" [class.locked]=\"s.locked\" [disabled]=\"s.locked\" (click)=\"s.go()\">\n <span class=\"sub-step-dot\">{{s.num}}</span>\n {{s.label}}\n </button>\n </div>\n\n <div class=\"sub-step-content\">\n <ng-container *ngIf=\"subStep === 'date'\">\n <div class=\"section-card card\">\n <div class=\"week-header\">\n <div>\n <h3 class=\"section-title mb-0\">Select a Date</h3>\n <p class=\"subtitle mb-0\">{{weekRangeLabel}}</p>\n </div>\n <div class=\"week-arrows\">\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"prevWeek()\" [disabled]=\"weekOffset <= 0\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"nextWeek()\" [disabled]=\"weekOffset >= maxWeekOffset\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"week-strip\">\n <button type=\"button\" class=\"week-day\" *ngFor=\"let d of weekDays\" [class.selected]=\"d.selected\"\n (click)=\"pickDay(d)\">\n <div class=\"week-day-dow\">{{d.dow}}</div>\n <div class=\"week-day-num\">{{d.num}}</div>\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'time'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title mb-0\">Select a Time</h3>\n <p class=\"subtitle\" *ngIf=\"selectedDateStr\">Available slots for {{selectedDateStr}}</p>\n <p class=\"subtitle mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n <div class=\"time-slot-grid overflow-scroll\" *ngIf=\"selectedDateStr\">\n <ng-container *ngIf=\"!slotsLoading; else slotsLoadingTpl\">\n <div class=\"time-slot rounded-2\" *ngFor=\"let time of slots\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time?.value}}</div>\n <p class=\"mb-0\" *ngIf=\"slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n <ng-template #slotsLoadingTpl>\n <p class=\"mb-0\">Loading available times...</p>\n </ng-template>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'details'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title\">Booking Details</h3>\n <div class=\"booking-for-line\">\n Booking for <strong>{{userDetails?.contact?.name}}</strong>\n <ng-container *ngIf=\"userDetails?.contact?.mobile\"> \u00B7 {{userDetails?.contact?.mobile}}</ng-container>\n <ng-container *ngIf=\"userDetails?.contact?.email\"> \u00B7 {{userDetails?.contact?.email}}</ng-container>\n </div>\n\n <ng-container *ngIf=\"mode === 'HOME_VISIT'\">\n <p class=\"policies-title mt-3 mb-2\" style=\"font-size:1rem;\">Shipping Address</p>\n\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Instructions (optional)</label>\n <textarea class=\"form-control form-textarea rounded-2\" [(ngModel)]=\"instructions\"></textarea>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div class=\"sub-step-footer\">\n <button type=\"button\" class=\"sub-back-btn\" [disabled]=\"subBackOff\" (click)=\"subBack()\">Back</button>\n <div class=\"sub-chosen-label\">{{subChosenLabel}}</div>\n <button type=\"button\" class=\"sub-next-btn\" *ngIf=\"subStep !== 'details'\" [disabled]=\"subNextOff\" (click)=\"subNext()\">Next</button>\n </div>\n </div>\n\n <div class=\"single-right section-card card\">\n <h3 class=\"section-title\">Your Shortlisted Designs</h3>\n <div class=\"design-row\" *ngFor=\"let it of productCartItems\">\n <div class=\"design-thumb\"></div>\n <div class=\"design-info\">\n <div class=\"design-name\">{{it.itemName}}</div>\n <div class=\"design-price\">\u20B9{{(it.sellingPrice ?? it.price ?? 0) * (it.quantity ?? 1)}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"add-more-btn\" (click)=\"goToListing()\">+ Add More Designs</button>\n\n <div class=\"summary-divider\"></div>\n\n <div class=\"summary-line\" *ngIf=\"mode !== 'HOME_VISIT' || homeVisitCharge <= 0\">\n <div class=\"summary-label\">Service:</div>\n <div class=\"free-label\">FREE</div>\n </div>\n <div class=\"summary-line\" *ngIf=\"mode === 'HOME_VISIT' && homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\">\u20B9{{homeVisitCharge}}</div>\n </div>\n\n <button class=\"continue-btn w-100 mt-2\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review Booking</button>\n <p class=\"footnote\">You will review everything on the next screen before it is confirmed.</p>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"review-wrap\">\n <div class=\"review-card card\">\n <div class=\"review-header\">Review your booking</div>\n <div class=\"review-row\" *ngFor=\"let rc of reviewRows\">\n <div class=\"review-k\">{{rc.k}}</div>\n <div class=\"review-v\">{{rc.v}}</div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button type=\"button\" class=\"review-back-btn\" (click)=\"backToForm()\">Back &amp; edit</button>\n <button type=\"button\" class=\"review-confirm-btn\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\">\n {{isProcessing ? 'Please wait...' : (mode === 'HOME_VISIT' ? 'Confirm Home Visit' : 'Confirm Video Call')}}\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.75rem;font-weight:600;color:var(--slate-800)!important;height:34px;padding:0 4px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}.wiz-container{width:100%;max-width:1120px}.wizard-banner{border-radius:var(--border-radius-lg);padding:1.125rem 1.5rem;background:var(--color-accent-gradient);box-shadow:var(--shadow-sm)}.wizard-banner-title{font-size:1.1rem;font-weight:700;color:#fff!important}.wizard-banner-desc{font-size:.85rem;line-height:1.5;color:#ffffffd9!important;padding-top:.2rem;max-width:520px}.sub-step-tabs{display:flex;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.sub-step-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;border:none;background:#fff;padding:.85rem 0;font-size:.85rem;font-weight:600;color:var(--slate-500)!important;cursor:pointer;border-bottom:2px solid transparent;transition:var(--transition-smooth)}.sub-step-tab.active{color:var(--slate-900)!important;border-bottom-color:var(--color-primary);background:var(--slate-50)}.sub-step-tab.locked{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-dot{width:20px;height:20px;border-radius:50%;background:var(--slate-200);color:var(--slate-500)!important;font-size:.7rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.sub-step-tab.active .sub-step-dot{background:var(--color-accent-gradient);color:#fff!important}.sub-step-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.85rem 1.25rem;box-shadow:var(--shadow-sm)}.sub-step-footer .sub-back-btn{width:auto;flex:0 0 auto;height:40px;font-size:.85rem;font-weight:600;color:var(--slate-600)!important;background:none;border:1.5px solid var(--slate-200);padding:0 18px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-back-btn:hover:not(:disabled){color:var(--slate-900)!important;background-color:var(--slate-100)}.sub-step-footer .sub-back-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-footer .sub-chosen-label{width:auto;flex:1 1 auto;font-size:.8rem;color:var(--slate-500)!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;text-align:center}.sub-step-footer .sub-next-btn{width:auto;flex:0 0 auto;height:40px;background:var(--color-accent-gradient);color:#fff!important;border:none;padding:0 22px;border-radius:var(--border-radius-md);font-size:.85rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-next-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.sub-step-footer .sub-next-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.single-grid{display:grid;grid-template-columns:1fr 360px;gap:1.5rem;align-items:start}.single-left{display:flex;flex-direction:column;gap:1.5rem}.single-right{align-self:flex-start;position:sticky;top:10px}.week-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:14px}.week-arrows{display:flex;gap:8px}.week-arrow-btn{width:34px;height:34px;border-radius:8px;border:1px solid var(--slate-200);background:#fff;color:var(--slate-700)!important;cursor:pointer;display:flex;align-items:center;justify-content:center}.week-arrow-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.week-strip{display:grid;grid-template-columns:repeat(7,1fr);gap:10px}.week-day{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem .25rem;cursor:pointer;transition:var(--transition-smooth);text-align:center}.week-day:hover{border-color:var(--slate-400)}.week-day.selected{background:var(--color-accent-gradient);border-color:transparent}.week-day.selected .week-day-dow,.week-day.selected .week-day-num{color:#fff!important}.week-day-dow{font-size:.75rem;font-weight:600;color:var(--slate-500)!important;text-transform:uppercase}.week-day-num{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-top:2px}.booking-for-line{font-size:.9rem;color:var(--slate-600)!important;padding:.85rem 1rem;background:var(--slate-50);border-radius:var(--border-radius-md);margin-bottom:.5rem}.booking-for-line strong{color:var(--slate-900)!important}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.design-row{display:flex;gap:13px;align-items:center;padding-bottom:1rem}.design-thumb{width:56px;height:56px;border-radius:8px;background:var(--slate-100);flex:none}.design-info{flex:1}.design-name{font-size:13.5px;color:var(--slate-900)!important;line-height:1.35}.design-price{font-size:13.5px;font-weight:600;color:var(--slate-900)!important;margin-top:3px}.add-more-btn{width:100%;height:44px;border:1.5px dashed var(--slate-300);border-radius:8px;background:none;color:var(--color-primary)!important;font-size:13px;font-weight:600;cursor:pointer;margin-bottom:1rem}.summary-divider{height:1px;background:var(--slate-100);margin-bottom:1rem}.summary-line{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.free-label{font-size:13.5px;font-weight:600;color:var(--color-success)!important}.footnote{font-size:11.5px;line-height:1.5;color:var(--slate-500)!important;text-align:center;margin:.75rem 0 0}.review-wrap{max-width:560px;margin:0 auto;display:flex;flex-direction:column;gap:16px}.review-card{border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.review-actions{display:flex;gap:12px}.review-actions .review-back-btn{flex:1;height:48px;border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);background:#fff;color:var(--slate-600)!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-back-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.review-actions .review-confirm-btn{flex:1;height:48px;border:none;border-radius:var(--border-radius-md);background:var(--color-accent-gradient);color:#fff!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-confirm-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.review-actions .review-confirm-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.review-header{padding:14px 18px;background:var(--slate-50);border-bottom:1px solid var(--slate-100);font-size:14.5px;font-weight:700;color:var(--slate-900)!important}.review-row{display:flex;justify-content:space-between;gap:16px;padding:12px 18px;border-bottom:1px solid var(--slate-100);font-size:13.5px}.review-row:last-child{border-bottom:none}.review-k{color:var(--slate-500)!important;flex-shrink:0}.review-v{color:var(--slate-900)!important;font-weight:500;text-align:right}@media screen and (max-width: 900px){.single-grid{grid-template-columns:1fr}.single-right{position:static}}@media screen and (max-width: 475px){.week-strip{gap:6px}}\n"] }]
26487
+ args: [{ selector: 'simpo-book-appointment', standalone: true, imports: [CommonModule, MatIcon, MatIconModule, FormsModule, MatDialogModule, ToastModule, HoverDirective, HoverElementsComponent, BackgroundDirective], providers: [MessageService], template: "<p-toast position=\"bottom-right\" [baseZIndex]=\"10000000000\" [autoZIndex]=\"true\"\n [showTransformOptions]=\"screenWidth < 475 ? 'translateY(-100%)' : ''\"></p-toast>\n<section class=\"main_section\" [id]=\"data?.id\" simpoHover (hovering)=\"showEditTabs($event)\"\n [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div [ngClass]=\"{'hover_effect': edit}\" *ngIf=\"showEditors\">\n <simpo-hover-elements [data]=\"data\" [index]=\"index\" [editOptions]=\"edit\"></simpo-hover-elements>\n </div>\n <div class=\"main_body w-100 d-flex justify-content-center\">\n <div class=\"wiz-container\">\n\n <ng-container *ngIf=\"step === 'form'\">\n <div class=\"single-grid\">\n <div class=\"single-left\">\n\n <div class=\"wizard-banner\" [id]=\"data?.id\" [simpoBackground]=\"backgroundInfo\" [style.--color-accent-gradient]=\"accentColor\">\n <div class=\"wizard-banner-title\">{{bannerTitle}}</div>\n <div class=\"wizard-banner-desc\">{{bannerDesc}}</div>\n </div>\n\n <div class=\"sub-step-tabs\">\n <button type=\"button\" class=\"sub-step-tab\" *ngFor=\"let s of subSteps; trackBy: trackBySubStepKey\"\n [class.active]=\"s.active\" [class.locked]=\"s.locked\" [disabled]=\"s.locked\" (click)=\"s.go()\">\n <span class=\"sub-step-dot\">{{s.num}}</span>\n {{s.label}}\n </button>\n </div>\n\n <div class=\"sub-step-content\">\n <ng-container *ngIf=\"subStep === 'date'\">\n <div class=\"section-card card\">\n <div class=\"week-header\">\n <div>\n <h3 class=\"section-title mb-0\">Select a Date</h3>\n <p class=\"subtitle mb-0\">{{weekRangeLabel}}</p>\n </div>\n <div class=\"week-arrows\">\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"prevWeek()\" [disabled]=\"weekOffset <= 0\">\n <mat-icon>chevron_left</mat-icon>\n </button>\n <button type=\"button\" class=\"week-arrow-btn\" (click)=\"nextWeek()\" [disabled]=\"weekOffset >= maxWeekOffset\">\n <mat-icon>chevron_right</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"week-strip\">\n <button type=\"button\" class=\"week-day\" *ngFor=\"let d of weekDays\" [class.selected]=\"d.selected\"\n (click)=\"pickDay(d)\">\n <div class=\"week-day-dow\">{{d.dow}}</div>\n <div class=\"week-day-num\">{{d.num}}</div>\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'time'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title mb-0\">Select a Time</h3>\n <p class=\"subtitle\" *ngIf=\"selectedDateStr\">Available slots for {{selectedDateStr}}</p>\n <p class=\"subtitle mb-0\" *ngIf=\"!selectedDateStr\">Pick a date to see available times.</p>\n <div class=\"time-slot-grid overflow-scroll\" *ngIf=\"selectedDateStr\">\n <ng-container *ngIf=\"!slotsLoading; else slotsLoadingTpl\">\n <div class=\"time-slot rounded-2\" *ngFor=\"let time of slots\" [class.selected]=\"time.selected\"\n (click)=\"selectSlot(time)\">{{time?.value}}</div>\n <p class=\"mb-0\" *ngIf=\"slots.length === 0\">No slots available for this date.</p>\n </ng-container>\n <ng-template #slotsLoadingTpl>\n <p class=\"mb-0\">Loading available times...</p>\n </ng-template>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"subStep === 'details'\">\n <div class=\"section-card card\">\n <h3 class=\"section-title\">Booking Details</h3>\n <div class=\"booking-for-line\">\n Booking for <strong>{{userDetails?.contact?.name}}</strong>\n <ng-container *ngIf=\"userDetails?.contact?.mobile\"> \u00B7 {{userDetails?.contact?.mobile}}</ng-container>\n <ng-container *ngIf=\"userDetails?.contact?.email\"> \u00B7 {{userDetails?.contact?.email}}</ng-container>\n </div>\n\n <ng-container *ngIf=\"mode === 'HOME_VISIT'\">\n <p class=\"policies-title mt-3 mb-2\" style=\"font-size:1rem;\">Shipping Address</p>\n\n <div class=\"shipping-info\" *ngIf=\"defaultAddress\">\n <div class=\"address-info\">\n <div class=\"address-name\">{{defaultAddress?.receiverName}} ({{defaultAddress?.addressType}})</div>\n <div class=\"address-details\">{{defaultAddress?.addressLine1}}, {{defaultAddress?.cityName}},\n {{defaultAddress?.stateName}}</div>\n <div class=\"mobile-number\">Mobile: {{defaultAddress?.receiverPhone}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"change-address-btn w-100\" (click)=\"changeAddress()\" *ngIf=\"defaultAddress\">\n CHANGE OR ADD ADDRESS\n </button>\n\n <div class=\"addLinks\" *ngIf=\"!defaultAddress\" (click)=\"addAddress()\">\n <mat-icon>add</mat-icon>\n <span class=\"ms-2\">Add an address</span>\n </div>\n\n <div class=\"mb-0 mt-3\">\n <label class=\"form-label d-flex align-items-center\">Instructions (optional)</label>\n <textarea class=\"form-control form-textarea rounded-2\" [(ngModel)]=\"instructions\"></textarea>\n </div>\n </ng-container>\n </div>\n </ng-container>\n </div>\n\n <div class=\"sub-step-footer\">\n <button type=\"button\" class=\"sub-back-btn\" [disabled]=\"subBackOff\" (click)=\"subBack()\">Back</button>\n <div class=\"sub-chosen-label\">{{subChosenLabel}}</div>\n <button type=\"button\" class=\"sub-next-btn\" *ngIf=\"subStep !== 'details'\" [disabled]=\"subNextOff\" (click)=\"subNext()\">Next</button>\n </div>\n </div>\n\n <div class=\"single-right section-card card\">\n <h3 class=\"section-title\">Your Shortlisted Designs</h3>\n <div class=\"design-row\" *ngFor=\"let it of productCartItems\">\n <div class=\"design-thumb\"></div>\n <div class=\"design-info\">\n <div class=\"design-name\">{{it.itemName}}</div>\n <div class=\"design-price\">\u20B9{{(it.sellingPrice ?? it.price ?? 0) * (it.quantity ?? 1)}}</div>\n </div>\n </div>\n <button type=\"button\" class=\"add-more-btn\" (click)=\"goToListing()\">+ Add More Designs</button>\n\n <div class=\"summary-divider\"></div>\n\n <div class=\"summary-line\" *ngIf=\"mode !== 'HOME_VISIT' || homeVisitCharge <= 0\">\n <div class=\"summary-label\">Service:</div>\n <div class=\"free-label\">FREE</div>\n </div>\n <div class=\"summary-line\" *ngIf=\"mode === 'HOME_VISIT' && homeVisitCharge > 0\">\n <div class=\"summary-label\">Home visit charge</div>\n <div class=\"summary-value\">\u20B9{{homeVisitCharge}}</div>\n </div>\n\n <button class=\"continue-btn w-100 mt-2\" [disabled]=\"invalid()\" (click)=\"goToReview()\">Review Booking</button>\n <p class=\"footnote\">You will review everything on the next screen before it is confirmed.</p>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'review'\">\n <div class=\"review-wrap\">\n <div class=\"review-card card\">\n <div class=\"review-header\">Review your booking</div>\n <div class=\"review-row\" *ngFor=\"let rc of reviewRows\">\n <div class=\"review-k\">{{rc.k}}</div>\n <div class=\"review-v\">{{rc.v}}</div>\n </div>\n </div>\n <div class=\"review-actions\">\n <button type=\"button\" class=\"review-back-btn\" (click)=\"backToForm()\">Back &amp; edit</button>\n <button type=\"button\" class=\"review-confirm-btn\" (click)=\"confirmBooking()\" [disabled]=\"isProcessing\">\n {{isProcessing ? 'Please wait...' : (mode === 'HOME_VISIT' ? 'Confirm Home Visit' : 'Confirm Video Call')}}\n </button>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"step === 'done'\">\n <div class=\"booking-confirmation\">\n <div class=\"success-icon\">\n <div class=\"checkmark-circle\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/881293c1758695578518success.gif\"\n class=\"w-100 h-100\" *ngIf=\"apiStatus\">\n <img src=\"https://d2z9497xp8xb12.cloudfront.net/prod-images/325000c1758695564518fail.gif\"\n class=\"w-100 h-100\" *ngIf=\"!apiStatus\">\n </div>\n </div>\n\n <div class=\"confirmation-content\">\n <h1 class=\"confirmation-title\">{{apiStatus ? 'Booking Confirmed!' : 'Booking Failed'}}</h1>\n <p class=\"confirmation-message\">\n {{apiStatus ? 'Your appointment has been successfully booked.':'Failed to book your appointment. Please\n try again later'}}\n </p>\n\n <div class=\"video-call-link-card d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus && mode === 'VIDEO_CALL' && bookingGroup?.videoCallLink\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Your Video Call Link</h3>\n <a [href]=\"bookingGroup.videoCallLink\" target=\"_blank\">{{bookingGroup.videoCallLink}}</a>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Appointment Details</h3>\n <div class=\"details-row\">\n <span class=\"detail-label\">{{productCartItems.length ? 'Products' : (mode === 'HOME_VISIT' ? 'Home Visit' : 'Video Call')}}</span>\n <span class=\"detail-value\">{{selectedDateStr}} at {{selectedSlot?.value ?? 'N/A'}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex w-100 align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <div class=\"details-card\">\n <h3 class=\"details-title\">Payment</h3>\n <div class=\"details-row\" *ngIf=\"homeVisitCharge > 0\">\n <span class=\"detail-label\">Home visit charge</span>\n <span class=\"detail-value\">\u20B9{{homeVisitCharge}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Total</span>\n <span class=\"detail-value\">\u20B9{{bookingTotal}}</span>\n </div>\n <div class=\"details-row\">\n <span class=\"detail-label\">Paid</span>\n <span class=\"detail-value\">\u20B9{{bookingPaid}}</span>\n </div>\n <div class=\"details-row\" *ngIf=\"bookingDue > 0\">\n <span class=\"detail-label\">Due</span>\n <span class=\"detail-value\">\u20B9{{bookingDue}}</span>\n </div>\n </div>\n </div>\n\n <div class=\"done-actions d-flex align-items-center justify-content-center\" *ngIf=\"apiStatus\">\n <button type=\"button\" class=\"done-btn done-btn-primary\" (click)=\"goToMyBookings()\">View my bookings</button>\n <button type=\"button\" class=\"done-btn done-btn-secondary\" (click)=\"goToListing()\">Keep shopping</button>\n </div>\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n</section>\n", styles: ["@import\"https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700;800&display=swap\";mat-icon{font-family:Material Icons!important}:host{--font-sans: \"Outfit\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;--slate-50: #f8fafc;--slate-100: #f1f5f9;--slate-200: #e2e8f0;--slate-300: #cbd5e1;--slate-400: #94a3b8;--slate-500: #64748b;--slate-600: #475569;--slate-700: #334155;--slate-800: #1e293b;--slate-900: #0f172a;--color-primary: #230860;--color-secondary: #00b6ff;--color-accent-gradient: linear-gradient(135deg, #230860 0%, #00b6ff 100%);--color-success: #10b981;--color-success-bg: #ecfdf5;--color-error: #ef4444;--color-error-bg: #fef2f2;--border-radius-sm: 8px;--border-radius-md: 12px;--border-radius-lg: 16px;--border-radius-xl: 24px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .05), 0 2px 4px -2px rgba(0, 0, 0, .05);--shadow-lg: 0 10px 15px -3px rgba(35, 8, 96, .05), 0 4px 6px -4px rgba(35, 8, 96, .05);--shadow-xl: 0 20px 25px -5px rgba(35, 8, 96, .08), 0 8px 10px -6px rgba(35, 8, 96, .08);--transition-smooth: all .3s cubic-bezier(.4, 0, .2, 1);--transition-bounce: all .4s cubic-bezier(.175, .885, .32, 1.275)}*{box-sizing:border-box;font-family:var(--font-sans)}.main_section{position:relative;height:100vh;background-color:var(--slate-50);display:flex;flex-direction:column;overflow:hidden}.hover_effect{position:absolute;width:100%;top:0;left:0;height:100%}.main_header{padding:15px;background:#fff;border-bottom:1px solid var(--slate-100);flex-shrink:0;box-shadow:0 2px 8px #00000003}.header{display:flex;align-items:center;justify-content:space-between}.back-btn{display:flex;align-items:center;justify-content:center;gap:.5rem;padding:.6rem 1.2rem;border-radius:var(--border-radius-md);background:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-700)!important;transition:var(--transition-smooth);font-weight:500;font-size:.9rem;cursor:pointer}.back-btn mat-icon{font-size:18px!important;width:18px!important;height:18px!important;color:var(--slate-700)!important;display:flex;align-items:center;justify-content:center}.back-btn:hover{background:var(--slate-100);transform:translate(-3px);color:var(--slate-900)!important}.header-title{flex-grow:1;text-align:right}.header-title h1{font-size:1.5rem;font-weight:700;margin-bottom:.2rem;color:var(--slate-900)!important;letter-spacing:-.025em}.header-title p{color:var(--slate-500)!important;font-size:.9rem;font-weight:500;margin-bottom:0}.progress-bar{width:100%;height:6px;background-color:var(--slate-100);margin-top:3px;border-radius:10px;overflow:hidden;position:relative}.progress-fill{height:100%;background:var(--color-accent-gradient);border-radius:10px;transition:width .5s cubic-bezier(.4,0,.2,1);position:relative}.progress-fill:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,#fff0,#ffffff4d,#fff0);animation:shimmer 2s infinite linear}@keyframes shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}.main_body{flex-grow:1;overflow-y:auto;padding:10px;display:flex;justify-content:center;background:var(--slate-50)}.w-60{width:100%;max-width:800px}.service_section,.location_section,.staff-listing,.date_section,.contact_section,.payment_section,.booking-confirmation{animation:slideUp .5s cubic-bezier(.16,1,.3,1) forwards}@keyframes slideUp{0%{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}h2{font-size:1.5rem;font-weight:700;color:var(--slate-900)!important;letter-spacing:-.02em;margin-bottom:.3rem}p.subtitle,.service-selection p,.location_section p,.staff-subtitle,.datetime-subtitle,.contact-subtitle,.payment-subtitle{color:var(--slate-500)!important;font-size:13px;margin-bottom:2rem}.services-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding-bottom:2rem}.service-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px}.service-card:hover{border-color:var(--slate-400);transform:translateY(-4px);box-shadow:var(--shadow-lg)}.service-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);display:flex;flex-direction:column;justify-content:space-between;height:100%;min-height:180px;transform:translateY(-2px)}.service-card-selected:before,.location-card-selected:before{content:\"\\2713\";position:absolute;top:-10px;right:-10px;background:var(--color-accent-gradient);color:#fff!important;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;font-weight:700;box-shadow:0 4px 8px #2308604d;animation:popIn .3s cubic-bezier(.175,.885,.32,1.275);z-index:10}@keyframes popIn{0%{transform:scale(0)}to{transform:scale(1)}}.service-header{display:flex;align-items:flex-start;gap:1rem;margin-bottom:1rem}.service-icon{width:48px;height:48px;border-radius:var(--border-radius-md);background-color:var(--slate-100);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.service-icon mat-icon{font-size:24px!important;width:24px!important;height:24px!important;color:var(--color-primary)!important}.service-card-selected .service-icon{background:var(--slate-900)}.service-card-selected .service-icon mat-icon{color:#fff!important}.service-info{flex-grow:1}.service-title{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;line-height:1.3;margin-bottom:.2rem}.service-price{font-size:1.25rem;font-weight:800;color:var(--slate-900)!important;text-align:right}.service-duration{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;text-align:right;margin-top:.1rem}.service-description{color:var(--slate-600)!important;font-size:.9rem;line-height:1.5;margin-bottom:1.25rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.home-visit{align-self:flex-start;display:inline-flex;align-items:center;gap:.5rem;font-size:.75rem;font-weight:600;color:var(--slate-700)!important;border:1px solid var(--slate-200);padding:.35rem .75rem;border-radius:20px;background-color:var(--slate-50);transition:var(--transition-smooth)}.home-visit img{width:14px;height:14px}.home-visit:before{content:\"\";display:inline-block;width:6px;height:6px;border-radius:50%;background-color:var(--color-success);box-shadow:0 0 #10b98166;animation:pulseGlow 1.8s infinite}@keyframes pulseGlow{0%{box-shadow:0 0 #10b981b3}70%{box-shadow:0 0 0 6px #10b98100}to{box-shadow:0 0 #10b98100}}.location-list{display:flex;flex-direction:column;gap:1.25rem;padding-bottom:2rem}.location-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm)}.location-card:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md)}.location-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:1.5rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px)}.location-content{display:flex;align-items:center}.location-info{display:flex;align-items:center;gap:1.25rem;width:100%}.location-icon{width:52px;height:52px;background-color:var(--slate-100);border-radius:var(--border-radius-md);display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:var(--transition-smooth)}.location-icon img{width:28px;height:28px}.location-card-selected .location-icon{background:var(--slate-900)}.location-details{flex-grow:1}.location-details h3{font-size:1.15rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.3rem}.location-details p{font-size:.9rem;color:var(--slate-500)!important;font-weight:450;line-height:1.4;margin-bottom:0}.search-container{width:100%;margin-bottom:1.25rem}.search-input-wrapper{width:100%;background-color:var(--slate-100);border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem 1rem;transition:var(--transition-smooth)}.search-input-wrapper:focus-within{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #23086014}.search-input{font-size:.95rem;font-weight:500;color:var(--slate-900)!important;background:transparent;outline:none;width:100%}.search-input::placeholder{color:var(--slate-400)}.search-icon{color:var(--slate-400)!important;font-size:20px!important;width:20px!important;height:20px!important}.clear-icon{color:var(--slate-400)!important;font-size:18px!important;width:18px!important;height:18px!important;transition:var(--transition-smooth)}.clear-icon:hover{color:var(--slate-600)!important}.staff-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:1rem;max-height:48vh;overflow-y:auto;padding-right:.5rem;padding-bottom:1rem}.staff-list::-webkit-scrollbar{width:6px}.staff-list::-webkit-scrollbar-track{background:var(--slate-50);border-radius:4px}.staff-list::-webkit-scrollbar-thumb{background:var(--slate-200);border-radius:4px}.staff-list::-webkit-scrollbar-thumb:hover{background:var(--slate-300)}.staff-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-sm);margin-bottom:0!important}.staff-card:hover{border-color:var(--slate-300);transform:translateY(-2px);box-shadow:var(--shadow-md)}.staff-card-selected{background:#fff;border:2px solid var(--color-primary);border-radius:var(--border-radius-lg);padding:.9rem 1.25rem;cursor:pointer;transition:var(--transition-bounce);position:relative;box-shadow:var(--shadow-xl);transform:translateY(-1px);margin-bottom:0!important}.staff-avatar{width:48px;height:48px;background:var(--color-accent-gradient);font-size:.95rem;font-weight:700;color:#fff!important;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;box-shadow:0 4px 10px #2308601a;letter-spacing:.5px;transition:var(--transition-smooth)}.staff-card-selected .staff-avatar{transform:scale(1.05)}.staff-name{font-size:1.05rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:.2rem;letter-spacing:-.015em}.staff-specialty{font-size:.8rem;color:var(--slate-500)!important;font-weight:600;margin-bottom:0;text-transform:uppercase;letter-spacing:.05em}.selection-indicator{display:flex;align-items:center;justify-content:center;margin-left:auto;padding-left:1rem}.checkmark-circle-mini{width:24px;height:24px;border:2px solid var(--slate-300);border-radius:50%;background-color:#fff;transition:var(--transition-bounce);color:#fff!important}.checkmark-circle-mini.selected{background:var(--color-accent-gradient);border-color:transparent;box-shadow:0 3px 8px #23086040}.checkmark-circle-mini mat-icon{font-size:14px!important;width:14px!important;height:14px!important;color:#fff!important;font-weight:800!important;display:flex;align-items:center;justify-content:center}.main_container{display:flex;gap:2rem;margin-bottom:2rem}.section-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;box-shadow:var(--shadow-sm);height:100%}.section-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:10px!important;letter-spacing:-.01em}.time_selection{max-height:420px;display:flex;flex-direction:column}.time_selection .row{flex-grow:1;overflow-y:auto;padding-right:.25rem;margin-top:10px}.time-slot{background:#fff;border:1px solid var(--slate-200);font-size:.75rem;font-weight:600;color:var(--slate-800)!important;height:34px;padding:0 4px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth);text-align:center;display:flex;align-items:center;justify-content:center;box-shadow:var(--shadow-sm)}.time-slot:hover{border-color:var(--slate-400);transform:translateY(-2px);box-shadow:var(--shadow-md);background-color:var(--slate-50)}.time-slot.selected{background:var(--color-accent-gradient);border-color:transparent;color:#fff!important;box-shadow:0 4px 12px #23086033}.form-section{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.75rem;box-shadow:var(--shadow-sm)}.form-label{font-size:.85rem;font-weight:600;color:var(--slate-700)!important;margin-bottom:.5rem;text-transform:uppercase;letter-spacing:.05em}.required-asterisk{color:var(--color-error);margin-left:2px}.form-control,.form-input,.form-textarea{width:100%;background-color:var(--slate-50);border:1px solid var(--slate-200);color:var(--slate-900)!important;font-size:.95rem;font-weight:500;padding:.75rem 1rem;border-radius:var(--border-radius-md);transition:var(--transition-smooth);outline:none}.form-control:focus,.form-input:focus,.form-textarea:focus{background-color:#fff;border-color:var(--color-primary);box-shadow:0 0 0 3px #2308601a}.form-textarea{min-height:100px;resize:vertical}.policies-container{background-color:#fff;border:1px solid var(--slate-200);padding:1.75rem;border-radius:var(--border-radius-lg);margin-top:1.5rem;box-shadow:var(--shadow-sm)}.policies-title{font-size:1.1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1.25rem}.policy-item{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1rem 1.25rem;cursor:pointer;transition:var(--transition-smooth);display:flex;justify-content:space-between;align-items:center}.policy-item:hover{background-color:var(--slate-100);border-color:var(--slate-300)}.policy-title{font-size:.95rem;font-weight:600;color:var(--slate-800)!important}.policy-arrow mat-icon{color:var(--slate-500)!important;transition:var(--transition-smooth)}.cancellation_policies{background-color:var(--slate-50);padding:1rem 1.5rem;border-left:3px solid var(--color-primary);border-radius:0 0 var(--border-radius-md) var(--border-radius-md);margin-top:-4px;margin-bottom:1rem;font-size:.9rem;color:var(--slate-600)!important;line-height:1.5}.acceptance-section{display:flex;align-items:center;gap:.75rem;margin-top:1.5rem}.custom-checkbox{width:20px;height:20px;border:2px solid var(--slate-300);border-radius:6px;cursor:pointer;transition:var(--transition-smooth);position:relative;appearance:none;background-color:#fff;outline:none}.custom-checkbox:checked{background:var(--color-accent-gradient);border-color:transparent}.custom-checkbox:checked:after{content:\"\\2713\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff!important;font-size:.75rem;font-weight:800}.acceptance-text{font-size:.95rem;color:var(--slate-700)!important;font-weight:500;-webkit-user-select:none;user-select:none;line-height:1.4}.booking-summary-card{background-color:#fff;border:1px solid var(--slate-200);padding:2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);position:relative}.booking-summary-card:after{content:\"\";position:absolute;bottom:-1px;left:0;right:0;height:10px;background-image:radial-gradient(circle,white 4px,transparent 5px);background-size:12px 12px;background-position:0 0;z-index:2}.summary-title{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important;border-bottom:2px dashed var(--slate-200);padding-bottom:1rem;margin-bottom:1.5rem;text-align:center}.summary-row{display:flex;justify-content:space-between;align-items:center;padding:.85rem 0;border-bottom:1px solid var(--slate-100)}.summary-label{font-size:.95rem;color:var(--slate-500)!important;font-weight:500}.summary-value{font-size:.95rem;color:var(--slate-900)!important;font-weight:600;text-align:right}.total-row{margin-top:1rem;padding-top:1.25rem;border-top:2px dashed var(--slate-200);border-bottom:none}.total-row .summary-label{font-size:1.25rem;font-weight:700;color:var(--slate-900)!important}.total-row .summary-value{font-size:1.5rem;font-weight:800;color:var(--color-primary)!important}.booking-confirmation{background:#fff;border:1px solid var(--slate-200);padding:3rem 2rem;border-radius:var(--border-radius-lg);box-shadow:var(--shadow-lg);display:flex;flex-direction:column;align-items:center;text-align:center;max-width:500px;margin:0 auto}.success-icon{margin-bottom:1.5rem}.checkmark-circle{width:96px;height:96px;display:flex;align-items:center;justify-content:center}.confirmation-title{font-size:1.5rem;font-weight:800;color:var(--slate-900)!important;margin-bottom:.5rem}.confirmation-message{font-size:1rem;color:var(--slate-500)!important;line-height:1.6;margin-bottom:2rem;font-weight:450}.details-card{background-color:var(--slate-50);border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:1.5rem;width:100%;margin-bottom:2rem;text-align:left}.details-title{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-bottom:1rem;text-transform:uppercase;letter-spacing:.05em}.details-row{display:flex;justify-content:space-between;padding:.5rem 0;border-bottom:1px dashed var(--slate-200)}.details-row:last-child{border-bottom:none}.detail-label{font-size:.85rem;color:var(--slate-500)!important;font-weight:500}.detail-value{font-size:.9rem;color:var(--slate-900)!important;font-weight:600}.done-actions{display:flex;gap:12px;width:100%}.done-btn{flex:1;max-width:220px;padding:.75rem 1.5rem;border-radius:var(--border-radius-md);font-size:.95rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth);border:none}.done-btn-primary{background:var(--color-accent-gradient);color:#fff!important;box-shadow:0 4px 10px #23086033}.done-btn-primary:hover{transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.done-btn-secondary{background:#fff;color:var(--slate-600)!important;border:1px solid var(--slate-200)}.done-btn-secondary:hover{background-color:var(--slate-100);color:var(--slate-900)!important}.continue-btn{background:var(--color-accent-gradient);color:#fff!important;border:none;padding:.75rem 2rem;border-radius:var(--border-radius-md);font-size:.95rem!important;font-weight:600;cursor:pointer;transition:var(--transition-smooth);box-shadow:0 4px 10px #23086033;width:max-content!important}.continue-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.continue-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.service-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(360px,1fr));gap:1.5rem;padding:0;width:100%}.skeleton-card{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:1.5rem;height:180px;display:flex;flex-direction:column;justify-content:space-between}.skeleton{background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border-radius:4px}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.skeleton-icon{width:48px;height:48px;border-radius:var(--border-radius-md)}.skeleton-title{height:20px;width:60%;margin-bottom:.5rem}.skeleton-price{height:20px;width:30%}.skeleton-duration{height:12px;width:25%;margin-top:.25rem}.skeleton-description{height:14px;width:85%}.skeleton-badge{height:28px;width:120px;border-radius:20px}.time-slot-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;width:100%}.skeleton-time-slot{height:42px;border-radius:var(--border-radius-md);background:linear-gradient(90deg,#f1f5f9 25%,#e2e8f0,#f1f5f9 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite linear;border:1px solid var(--slate-100)}@media screen and (max-width: 475px){.main_header{padding:1rem}.header-title h1{font-size:1.25rem}.back-btn{padding:.5rem .8rem}.back-btn span{display:none}.main_body{padding:15px}.services-grid{grid-template-columns:1fr;gap:1rem}.staff-list{grid-template-columns:1fr!important;gap:.85rem!important}.service-card,.service-card-selected{min-height:auto}.main_container{flex-direction:column;gap:1.5rem}.details_container{gap:1.5rem}.details_container>.d-flex{flex-direction:column;gap:1.5rem}.details_container>.d-flex>div{width:100%!important}.booking-summary-card{padding:1.25rem}.summary-title{font-size:1.15rem}.total-row .summary-label{font-size:1.1rem}.total-row .summary-value{font-size:1.3rem}.main_footer{padding:1rem}.continue-btn{padding:.75rem 1.5rem}}h1{font-size:24px!important;font-weight:600!important}.wiz-container{width:100%;max-width:1120px}.wizard-banner{border-radius:var(--border-radius-lg);padding:1.125rem 1.5rem;background:var(--color-accent-gradient);box-shadow:var(--shadow-sm)}.wizard-banner-title{font-size:1.1rem;font-weight:700;color:#fff!important}.wizard-banner-desc{font-size:.85rem;line-height:1.5;color:#ffffffd9!important;padding-top:.2rem;max-width:520px}.sub-step-tabs{display:flex;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.sub-step-tab{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;border:none;background:#fff;padding:.85rem 0;font-size:.85rem;font-weight:600;color:var(--slate-500)!important;cursor:pointer;border-bottom:2px solid transparent;transition:var(--transition-smooth)}.sub-step-tab.active{color:var(--slate-900)!important;border-bottom-color:var(--color-primary);background:var(--slate-50)}.sub-step-tab.locked{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-dot{width:20px;height:20px;border-radius:50%;background:var(--slate-200);color:var(--slate-500)!important;font-size:.7rem;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.sub-step-tab.active .sub-step-dot{background:var(--color-accent-gradient);color:#fff!important}.sub-step-footer{display:flex;align-items:center;justify-content:space-between;gap:12px;background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);padding:.85rem 1.25rem;box-shadow:var(--shadow-sm)}.sub-step-footer .sub-back-btn{width:auto;flex:0 0 auto;height:40px;font-size:.85rem;font-weight:600;color:var(--slate-600)!important;background:none;border:1.5px solid var(--slate-200);padding:0 18px;border-radius:var(--border-radius-md);cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-back-btn:hover:not(:disabled){color:var(--slate-900)!important;background-color:var(--slate-100)}.sub-step-footer .sub-back-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.sub-step-footer .sub-chosen-label{width:auto;flex:1 1 auto;font-size:.8rem;color:var(--slate-500)!important;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;text-align:center}.sub-step-footer .sub-next-btn{width:auto;flex:0 0 auto;height:40px;background:var(--color-accent-gradient);color:#fff!important;border:none;padding:0 22px;border-radius:var(--border-radius-md);font-size:.85rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.sub-step-footer .sub-next-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.sub-step-footer .sub-next-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.single-grid{display:grid;grid-template-columns:1fr 360px;gap:1.5rem;align-items:start}.single-left{display:flex;flex-direction:column;gap:1.5rem}.single-right{align-self:flex-start;position:sticky;top:10px}.week-header{display:flex;align-items:center;justify-content:space-between;padding-bottom:14px}.week-arrows{display:flex;gap:8px}.week-arrow-btn{width:34px;height:34px;border-radius:8px;border:1px solid var(--slate-200);background:#fff;color:var(--slate-700)!important;cursor:pointer;display:flex;align-items:center;justify-content:center}.week-arrow-btn:disabled{color:var(--slate-300)!important;cursor:not-allowed}.week-strip{display:grid;grid-template-columns:repeat(7,1fr);gap:10px}.week-day{background:#fff;border:1px solid var(--slate-200);border-radius:var(--border-radius-md);padding:.6rem .25rem;cursor:pointer;transition:var(--transition-smooth);text-align:center}.week-day:hover{border-color:var(--slate-400)}.week-day.selected{background:var(--color-accent-gradient);border-color:transparent}.week-day.selected .week-day-dow,.week-day.selected .week-day-num{color:#fff!important}.week-day-dow{font-size:.75rem;font-weight:600;color:var(--slate-500)!important;text-transform:uppercase}.week-day-num{font-size:1rem;font-weight:700;color:var(--slate-900)!important;margin-top:2px}.booking-for-line{font-size:.9rem;color:var(--slate-600)!important;padding:.85rem 1rem;background:var(--slate-50);border-radius:var(--border-radius-md);margin-bottom:.5rem}.booking-for-line strong{color:var(--slate-900)!important}.shipping-info{border-radius:10px;padding:20px;margin-bottom:12px;border:1px solid var(--slate-200);box-shadow:var(--shadow-sm)}.address-info{margin-bottom:0}.address-name{font-weight:700;margin-bottom:8px;color:var(--slate-900)!important}.address-details{color:var(--slate-500)!important;margin-bottom:8px}.mobile-number{font-weight:700;color:var(--slate-900)!important;font-size:15px}.change-address-btn{font-size:.85rem!important;font-weight:700!important;padding:10px;background:#fff;border:1px solid var(--slate-200);border-radius:8px;color:var(--slate-900)!important;cursor:pointer;transition:var(--transition-smooth)}.change-address-btn:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.addLinks{padding:14px;border:1px dashed var(--slate-300);display:flex;align-items:center;justify-content:center;cursor:pointer;border-radius:8px;color:var(--slate-500)!important;margin-bottom:12px}.addLinks:hover{border-color:var(--color-primary);color:var(--color-primary)!important}.design-row{display:flex;gap:13px;align-items:center;padding-bottom:1rem}.design-thumb{width:56px;height:56px;border-radius:8px;background:var(--slate-100);flex:none}.design-info{flex:1}.design-name{font-size:13.5px;color:var(--slate-900)!important;line-height:1.35}.design-price{font-size:13.5px;font-weight:600;color:var(--slate-900)!important;margin-top:3px}.add-more-btn{width:100%;height:44px;border:1.5px dashed var(--slate-300);border-radius:8px;background:none;color:var(--color-primary)!important;font-size:13px;font-weight:600;cursor:pointer;margin-bottom:1rem}.summary-divider{height:1px;background:var(--slate-100);margin-bottom:1rem}.summary-line{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem}.free-label{font-size:13.5px;font-weight:600;color:var(--color-success)!important}.footnote{font-size:11.5px;line-height:1.5;color:var(--slate-500)!important;text-align:center;margin:.75rem 0 0}.review-wrap{max-width:560px;margin:0 auto;display:flex;flex-direction:column;gap:16px}.review-card{border:1px solid var(--slate-200);border-radius:var(--border-radius-lg);overflow:hidden}.review-actions{display:flex;gap:12px}.review-actions .review-back-btn{flex:1;height:48px;border:1.5px solid var(--slate-200);border-radius:var(--border-radius-md);background:#fff;color:var(--slate-600)!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-back-btn:hover{color:var(--slate-900)!important;background-color:var(--slate-100)}.review-actions .review-confirm-btn{flex:1;height:48px;border:none;border-radius:var(--border-radius-md);background:var(--color-accent-gradient);color:#fff!important;font-size:.9rem;font-weight:600;cursor:pointer;transition:var(--transition-smooth)}.review-actions .review-confirm-btn:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 6px 15px #2308604d}.review-actions .review-confirm-btn:disabled{background:var(--slate-200)!important;color:var(--slate-400)!important;cursor:not-allowed!important;box-shadow:none!important}.review-header{padding:14px 18px;background:var(--slate-50);border-bottom:1px solid var(--slate-100);font-size:14.5px;font-weight:700;color:var(--slate-900)!important}.review-row{display:flex;justify-content:space-between;gap:16px;padding:12px 18px;border-bottom:1px solid var(--slate-100);font-size:13.5px}.review-row:last-child{border-bottom:none}.review-k{color:var(--slate-500)!important;flex-shrink:0}.review-v{color:var(--slate-900)!important;font-weight:500;text-align:right}@media screen and (max-width: 900px){.single-grid{grid-template-columns:1fr}.single-right{position:static}}@media screen and (max-width: 475px){.week-strip{gap:6px}}\n"] }]
26435
26488
  }], ctorParameters: () => [{ type: i2$2.ActivatedRoute }, { type: i2$2.Router }, { type: RestService }, { type: EventsService }, { type: i6$1.MessageService }, { type: StorageServiceService }, { type: BookingProductCartService }, { type: i3$2.MatDialog }], propDecorators: { data: [{
26436
26489
  type: Input
26437
26490
  }], index: [{