Menu

Change language

GitHub repo

Benefits Enrollment Portal

blockhr

Employee benefits open enrollment portal with interactive medical, dental, and vision plan comparisons, customizable 401(k) contribution slider with real-time employer match calculation, and a sticky paycheck impact summary.

Installation

$npx uipkge-ng@latest add benefits-enrollment-portal
Manifest:https://uipkge.dev/r/angular/benefits-enrollment-portal.jsonInstalls to:src/app/components/blocks/benefits-enrollment-portal/

Variants

Loading interactive previews…

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

MedicalPlan
interface MedicalPlan {
  id: string
  name: string
  carrier: string
  badge?: string
  badgeVariant?: 'default' | 'secondary' | 'outline'
  employeeCostPerPaycheck: number
  employerCostPerMonth: number
  deductible: string
  outOfPocketMax: string
  copayOrCoinsurance: string
  hsaSeed: number
  description: string
  highlights: string[]
}
DentalPlan
interface DentalPlan {
  id: string
  name: string
  carrier: string
  badge?: string
  badgeVariant?: 'default' | 'secondary' | 'outline'
  employeeCostPerPaycheck: number
  employerCostPerMonth: number
  annualMax: string
  preventive: string
  basic: string
  majorOrOrtho: string
  description: string
}
VisionPlan
interface VisionPlan {
  id: string
  name: string
  carrier: string
  badge?: string
  badgeVariant?: 'default' | 'secondary' | 'outline'
  employeeCostPerPaycheck: number
  employerCostPerMonth: number
  examCopay: string
  frameAllowance: string
  lenses: string
  description: string
}

Files installed (2)

  • src/app/components/blocks/benefits-enrollment-portal/benefits-enrollment-portal.component.ts54.5 kB
    // Employee benefits open enrollment portal with interactive medical, dental, and vision
    // plan comparisons, customizable 401(k) contribution slider with real-time employer match
    // calculation, and a sticky paycheck impact summary. Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, Input, OnInit, computed, signal } from '@angular/core'
    import {
      AlertCircle,
      Check,
      CheckCircle2,
      Clock,
      Download,
      Eye,
      FileCheck,
      FileSignature,
      HeartPulse,
      LucideAngularModule,
      Percent,
      PiggyBank,
      RefreshCw,
      ShieldCheck,
      User,
      Users,
    } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import {
      UiCardComponent,
      UiCardContentComponent,
      UiCardDescriptionComponent,
      UiCardFooterComponent,
      UiCardHeaderComponent,
      UiCardTitleComponent,
    } from '@/ui/card/card.component'
    import { UiRadioGroupComponent, UiRadioGroupItemComponent } from '@/ui/radio-group/radio-group.component'
    import { UiSeparatorComponent } from '@/ui/separator/separator.component'
    import { UiSliderComponent } from '@/ui/slider/slider.component'
    
    export interface MedicalPlan {
      id: string
      name: string
      carrier: string
      badge?: string
      badgeVariant?: 'default' | 'secondary' | 'outline'
      employeeCostPerPaycheck: number
      employerCostPerMonth: number
      deductible: string
      outOfPocketMax: string
      copayOrCoinsurance: string
      hsaSeed: number
      description: string
      highlights: string[]
    }
    
    const MEDICAL_PLANS: MedicalPlan[] = [
      {
        id: 'medical-ppo-hsa',
        name: 'BlueCross PPO High Deductible + HSA',
        carrier: 'BlueCross BlueShield',
        badge: 'Popular · HSA Eligible',
        badgeVariant: 'secondary',
        employeeCostPerPaycheck: 85,
        employerCostPerMonth: 450,
        deductible: '$1,600 ind / $3,200 fam',
        outOfPocketMax: '$4,000 ind / $8,000 fam',
        copayOrCoinsurance: '10% after deductible',
        hsaSeed: 500,
        description: 'Triple tax-advantaged health savings account with an employer-funded annual HSA contribution.',
        highlights: [
          '$500 annual employer HSA contribution funded on Jan 1',
          '100% preventive care covered in-network with $0 deductible',
          'Flexible nationwide PPO specialist access without referrals',
        ],
      },
      {
        id: 'medical-gold-ppo',
        name: 'BlueCross Gold Premier PPO',
        carrier: 'BlueCross BlueShield',
        badge: 'Low $250 Deductible',
        badgeVariant: 'outline',
        employeeCostPerPaycheck: 180,
        employerCostPerMonth: 520,
        deductible: '$250 ind / $500 fam',
        outOfPocketMax: '$2,500 ind / $5,000 fam',
        copayOrCoinsurance: '$20 Primary / $40 Specialist',
        hsaSeed: 0,
        description: 'Predictable low-copay coverage designed for frequent medical care, prescriptions, and peace of mind.',
        highlights: [
          'Ultra-low $250 individual deductible for comprehensive care',
          '$20 primary care & $40 specialist fixed office visit copays',
          'Tier 1 generic prescriptions covered at $10 copay',
        ],
      },
      {
        id: 'medical-kaiser-hmo',
        name: 'Kaiser Permanente HMO',
        carrier: 'Kaiser Permanente',
        badge: '$0 Deductible',
        badgeVariant: 'outline',
        employeeCostPerPaycheck: 40,
        employerCostPerMonth: 420,
        deductible: '$0 ind / $0 fam',
        outOfPocketMax: '$1,500 ind / $3,000 fam',
        copayOrCoinsurance: '$15 Primary / $25 Specialist',
        hsaSeed: 0,
        description: 'Integrated in-network HMO coverage with zero deductible and lowest payroll deduction.',
        highlights: [
          '$0 deductible with everything under one roof at Kaiser centers',
          '$15 copay for routine medical and virtual telehealth visits',
          'Lowest bi-weekly payroll deduction across all medical tiers',
        ],
      },
    ]
    
    export interface DentalPlan {
      id: string
      name: string
      carrier: string
      badge?: string
      badgeVariant?: 'default' | 'secondary' | 'outline'
      employeeCostPerPaycheck: number
      employerCostPerMonth: number
      annualMax: string
      preventive: string
      basic: string
      majorOrOrtho: string
      description: string
    }
    
    const DENTAL_PLANS: DentalPlan[] = [
      {
        id: 'dental-comprehensive',
        name: 'Delta Dental Premier Comprehensive',
        carrier: 'Delta Dental',
        badge: 'Comprehensive · Ortho Included',
        badgeVariant: 'secondary',
        employeeCostPerPaycheck: 14,
        employerCostPerMonth: 35,
        annualMax: '$2,000 / member / yr',
        preventive: '100% (2 cleanings & exams / yr)',
        basic: '80% coverage (fillings & endodontics)',
        majorOrOrtho: '50% coverage ($1,500 lifetime ortho)',
        description: 'Complete coverage for preventative cleanings, major restorative procedures, and orthodontic care.',
      },
      {
        id: 'dental-basic',
        name: 'Delta Dental Basic',
        carrier: 'Delta Dental',
        badge: 'Basic Preventive',
        badgeVariant: 'outline',
        employeeCostPerPaycheck: 5,
        employerCostPerMonth: 20,
        annualMax: '$1,000 / member / yr',
        preventive: '100% (2 cleanings / yr)',
        basic: '50% coverage',
        majorOrOrtho: 'Not covered',
        description: 'Essential preventive dental care for routine bi-annual cleanings, exams, and basic cavity fillings.',
      },
      {
        id: 'dental-waive',
        name: 'Waive Dental Coverage',
        carrier: 'Decline',
        employeeCostPerPaycheck: 0,
        employerCostPerMonth: 0,
        annualMax: '$0',
        preventive: 'None',
        basic: 'None',
        majorOrOrtho: 'None',
        description: 'Decline dental insurance coverage for the 2026-2027 plan year.',
      },
    ]
    
    export interface VisionPlan {
      id: string
      name: string
      carrier: string
      badge?: string
      badgeVariant?: 'default' | 'secondary' | 'outline'
      employeeCostPerPaycheck: number
      employerCostPerMonth: number
      examCopay: string
      frameAllowance: string
      lenses: string
      description: string
    }
    
    const VISION_PLANS: VisionPlan[] = [
      {
        id: 'vision-choice-plus',
        name: 'VSP Vision Choice Plus',
        carrier: 'VSP Vision Care',
        badge: '$200 Frame Allowance',
        badgeVariant: 'secondary',
        employeeCostPerPaycheck: 8,
        employerCostPerMonth: 12,
        examCopay: '$10 copay (every 12 mo)',
        frameAllowance: '$200 allowance + 20% off overage',
        lenses: 'Progressives & anti-glare covered in full',
        description: 'Premium vision coverage with generous designer frame allowances and full progressive lens coverage.',
      },
      {
        id: 'vision-standard',
        name: 'VSP Standard Vision',
        carrier: 'VSP Vision Care',
        badge: 'Standard',
        badgeVariant: 'outline',
        employeeCostPerPaycheck: 3,
        employerCostPerMonth: 8,
        examCopay: '$15 copay (every 12 mo)',
        frameAllowance: '$120 frame allowance',
        lenses: 'Standard single-vision lenses covered',
        description: 'Core vision benefit for annual eye exams and standard prescription glasses.',
      },
      {
        id: 'vision-waive',
        name: 'Waive Vision Coverage',
        carrier: 'Decline',
        employeeCostPerPaycheck: 0,
        employerCostPerMonth: 0,
        examCopay: '$0',
        frameAllowance: '$0',
        lenses: 'None',
        description: 'Decline vision insurance coverage for the 2026-2027 plan year.',
      },
    ]
    
    const SLIDER_MARKS: Record<number, string> = {
      1: '1%',
      4: '4%',
      6: '6% (Max Match)',
      10: '10%',
      15: '15%',
      20: '20%',
    }
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-benefits-enrollment-portal, [ui-benefits-enrollment-portal]',
      standalone: true,
      // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [
        LucideAngularModule,
        UiBadgeComponent,
        UiButtonComponent,
        UiCardComponent,
        UiCardContentComponent,
        UiCardDescriptionComponent,
        UiCardFooterComponent,
        UiCardHeaderComponent,
        UiCardTitleComponent,
        UiRadioGroupComponent,
        UiRadioGroupItemComponent,
        UiSeparatorComponent,
        UiSliderComponent,
      ],
      template: `
        <div data-slot="benefits-enrollment-portal" [class]="rootClass">
          <!-- Header Banner -->
          <div class="border-border bg-card relative overflow-hidden rounded-xl border p-6 shadow-xs">
            <div class="flex flex-col gap-5 lg:flex-row lg:items-center lg:justify-between">
              <div class="space-y-2">
                <div class="flex flex-wrap items-center gap-2.5">
                  <span
                    ui-badge
                    wrap
                    variant="outline"
                    class="border-warning/30 bg-warning/10 text-warning max-w-full gap-1.5 px-3 py-1 text-left text-xs font-semibold"
                  >
                    <lucide-icon [img]="Clock" class="size-3.5" />
                    Open Enrollment Period Ends {{ deadlineDate }} · {{ daysRemaining }} Days Left
                  </span>
                  @if (isSubmitted()) {
                    <span
                      ui-badge
                      variant="secondary"
                      class="border-success/30 bg-success/10 text-success gap-1 text-xs font-semibold"
                    >
                      <lucide-icon [img]="CheckCircle2" class="size-3.5" />
                      Elections Submitted &amp; Signed
                    </span>
                  }
                </div>
    
                <div>
                  <h1 class="text-foreground text-2xl font-bold tracking-tight sm:text-3xl">
                    Annual Benefits Open Enrollment
                  </h1>
                  <p class="text-muted-foreground mt-1 text-sm sm:text-base">
                    Select your health coverage, retirement matching, and ancillary wellness plans for the 2026-2027 plan
                    year.
                  </p>
                </div>
    
                <!-- Employee metadata strip -->
                <div
                  class="border-border/60 bg-muted/40 text-muted-foreground mt-3 inline-flex flex-wrap items-center gap-x-4 gap-y-1.5 rounded-lg border px-3.5 py-2 text-xs"
                >
                  <div class="text-foreground flex items-center gap-1.5 font-medium">
                    <lucide-icon [img]="User" class="text-primary size-3.5" />
                    <span>{{ employeeName }}</span>
                  </div>
                  <div class="flex items-center gap-1.5">
                    <lucide-icon [img]="Users" class="size-3.5" />
                    <span
                      >Tier: <strong class="text-foreground font-medium">{{ coverageTier }}</strong></span
                    >
                  </div>
                  <div>
                    <span
                      >ID: <strong class="text-foreground font-mono font-medium">{{ employeeId }}</strong></span
                    >
                  </div>
                  <div>
                    <span
                      >Base:
                      <strong class="text-foreground font-medium tabular-nums"
                        >\${{ annualSalary.toLocaleString('en-US') }}/yr</strong
                      ></span
                    >
                  </div>
                </div>
              </div>
    
              <div class="flex flex-col gap-2.5 sm:flex-row lg:flex-col lg:items-end">
                @if (!isSubmitted()) {
                  <button ui-button size="lg" class="gap-2 font-semibold shadow-xs" (click)="showSignModal.set(true)">
                    <lucide-icon [img]="FileSignature" class="size-4" />
                    Save Selections &amp; Sign
                  </button>
                } @else {
                  <button
                    ui-button
                    variant="outline"
                    size="lg"
                    class="border-success/40 bg-success/5 text-success hover:bg-success/10 gap-2 font-semibold"
                    (click)="handleResetEnrollment()"
                  >
                    <lucide-icon [img]="RefreshCw" class="size-4" />
                    Modify My Elections
                  </button>
                }
    
                <p class="text-muted-foreground text-xs lg:text-right">
                  Changes take effect <span class="text-foreground font-medium">October 1, 2026</span>
                </p>
              </div>
            </div>
          </div>
    
          <!-- Submitted Banner (If Confirmed) -->
          @if (isSubmitted()) {
            <div
              class="border-success/30 bg-success/10 text-foreground flex flex-col items-start justify-between gap-4 rounded-xl border p-4 sm:flex-row sm:items-center"
            >
              <div class="flex flex-wrap items-start gap-3">
                <div
                  class="border-success/30 bg-success/20 text-success mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-lg border"
                >
                  <lucide-icon [img]="Check" class="size-4" />
                </div>
                <div>
                  <p class="text-foreground text-sm font-semibold">
                    Enrollment Signed &amp; Confirmed for Plan Year 2026-2027
                  </p>
                  <p class="text-muted-foreground mt-0.5 text-xs">
                    Confirmation Reference: <span class="text-foreground font-mono font-medium">#BEN-2026-89241</span> ·
                    Signed by {{ employeeName }} on August 21, 2026.
                  </p>
                </div>
              </div>
              <button ui-button aria-label="Download attachment" variant="outline" size="sm" class="gap-1.5 text-xs">
                <lucide-icon [img]="Download" class="size-3.5" />
                Download Summary PDF
              </button>
            </div>
          }
    
          <!-- Main 2-Column Grid: Plan Options (Col 8) + Sticky Paycheck Impact (Col 4) -->
          <div class="grid grid-cols-1 gap-8 lg:grid-cols-12 lg:items-start">
            <!-- Plan Selection Flow -->
            <div class="space-y-8 lg:col-span-8">
              <!-- Category 1: Medical Health Plan -->
              <div ui-card class="border-border shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex flex-wrap items-center justify-between gap-3 sm:flex-nowrap">
                    <div class="flex items-center gap-2.5">
                      <div
                        class="border-primary/20 bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-lg border"
                      >
                        <lucide-icon [img]="HeartPulse" class="size-4" />
                      </div>
                      <div>
                        <h3 ui-card-title class="text-base sm:text-lg">1. Medical Health Plan</h3>
                        <p ui-card-description>
                          Comprehensive inpatient, outpatient, prescription, and preventive medical coverage.
                        </p>
                      </div>
                    </div>
                    <span ui-badge variant="secondary" class="text-xs"> 3 Plans Available </span>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-4">
                  <ui-radio-group [value]="selectedMedical()" (valueChange)="selectedMedical.set($event)" class="gap-3.5">
                    @for (plan of medicalPlans; track plan.id) {
                      <div
                        role="button"
                        tabindex="0"
                        [attr.aria-pressed]="selectedMedical() === plan.id"
                        [class]="planCardClass(selectedMedical() === plan.id)"
                        (click)="selectedMedical.set(plan.id)"
                        (keydown.enter)="selectedMedical.set(plan.id)"
                        (keydown.space)="$event.preventDefault(); selectedMedical.set(plan.id)"
                      >
                        <div class="flex flex-wrap items-start justify-between gap-3">
                          <div class="flex flex-wrap items-start gap-3">
                            <ui-radio-group-item [id]="plan.id" [value]="plan.id" class="mt-0.5" />
                            <div class="space-y-1">
                              <div class="flex flex-wrap items-center gap-2">
                                <label
                                  [for]="plan.id"
                                  class="text-foreground cursor-pointer text-sm font-semibold sm:text-base"
                                >
                                  {{ plan.name }}
                                </label>
                                @if (plan.badge) {
                                  <span ui-badge [variant]="plan.badgeVariant ?? 'outline'" class="text-xs font-medium">
                                    {{ plan.badge }}
                                  </span>
                                }
                              </div>
                              <p class="text-muted-foreground text-xs">{{ plan.carrier }} · {{ plan.description }}</p>
                            </div>
                          </div>
    
                          <div class="shrink-0 text-right">
                            <div class="flex items-baseline justify-end gap-1">
                              <span class="text-foreground text-lg font-bold tabular-nums sm:text-xl">
                                \${{ plan.employeeCostPerPaycheck }}
                              </span>
                              <span class="text-muted-foreground text-xs font-normal">/ paycheck</span>
                            </div>
                            <p class="text-muted-foreground text-xs">
                              Employer pays
                              <span class="text-foreground font-medium tabular-nums"
                                >\${{ plan.employerCostPerMonth }}/mo</span
                              >
                            </p>
                          </div>
                        </div>
    
                        <!-- Plan Benefit Matrix Details -->
                        <div
                          class="border-border/60 bg-card/60 mt-1 grid grid-cols-2 gap-2.5 rounded-lg border p-3 text-xs sm:grid-cols-4"
                        >
                          <div>
                            <span class="text-muted-foreground block">Annual Deductible</span>
                            <span class="text-foreground font-semibold tabular-nums">{{ plan.deductible }}</span>
                          </div>
                          <div>
                            <span class="text-muted-foreground block">Out-of-Pocket Max</span>
                            <span class="text-foreground font-semibold tabular-nums">{{ plan.outOfPocketMax }}</span>
                          </div>
                          <div>
                            <span class="text-muted-foreground block">Primary / Specialist</span>
                            <span class="text-foreground font-semibold">{{ plan.copayOrCoinsurance }}</span>
                          </div>
                          <div>
                            <span class="text-muted-foreground block">HSA Company Seed</span>
                            <span
                              [class]="
                                plan.hsaSeed > 0
                                  ? 'text-success font-semibold tabular-nums'
                                  : 'text-muted-foreground font-medium'
                              "
                            >
                              {{ plan.hsaSeed > 0 ? '$' + plan.hsaSeed + ' / yr' : 'Not eligible' }}
                            </span>
                          </div>
                        </div>
    
                        <!-- Plan Bullet Highlights -->
                        <ul class="text-muted-foreground mt-0.5 space-y-1 text-xs">
                          @for (highlight of plan.highlights; track highlight) {
                            <li class="flex items-center gap-2">
                              <lucide-icon [img]="Check" class="text-primary size-3.5 shrink-0" />
                              <span>{{ highlight }}</span>
                            </li>
                          }
                        </ul>
                      </div>
                    }
                  </ui-radio-group>
                </div>
              </div>
    
              <!-- Category 2: Dental Plan -->
              <div ui-card class="border-border shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex flex-wrap items-center justify-between gap-3 sm:flex-nowrap">
                    <div class="flex items-center gap-2.5">
                      <div
                        class="border-primary/20 bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-lg border"
                      >
                        <lucide-icon [img]="ShieldCheck" class="size-4" />
                      </div>
                      <div>
                        <h3 ui-card-title class="text-base sm:text-lg">2. Dental Plan</h3>
                        <p ui-card-description>
                          Preventive exams, cleanings, restorative treatments, and orthodontic benefits.
                        </p>
                      </div>
                    </div>
                    <span ui-badge variant="secondary" class="text-xs"> 2 Plans + Waive </span>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-4">
                  <ui-radio-group [value]="selectedDental()" (valueChange)="selectedDental.set($event)" class="gap-3.5">
                    @for (plan of dentalPlans; track plan.id) {
                      <div
                        role="button"
                        tabindex="0"
                        [attr.aria-pressed]="selectedDental() === plan.id"
                        [class]="planCardClass(selectedDental() === plan.id)"
                        (click)="selectedDental.set(plan.id)"
                        (keydown.enter)="selectedDental.set(plan.id)"
                        (keydown.space)="$event.preventDefault(); selectedDental.set(plan.id)"
                      >
                        <div class="flex flex-wrap items-start justify-between gap-3">
                          <div class="flex flex-wrap items-start gap-3">
                            <ui-radio-group-item [id]="plan.id" [value]="plan.id" class="mt-0.5" />
                            <div class="space-y-1">
                              <div class="flex flex-wrap items-center gap-2">
                                <label
                                  [for]="plan.id"
                                  class="text-foreground cursor-pointer text-sm font-semibold sm:text-base"
                                >
                                  {{ plan.name }}
                                </label>
                                @if (plan.badge) {
                                  <span ui-badge [variant]="plan.badgeVariant ?? 'outline'" class="text-xs font-medium">
                                    {{ plan.badge }}
                                  </span>
                                }
                              </div>
                              <p class="text-muted-foreground text-xs">{{ plan.carrier }} · {{ plan.description }}</p>
                            </div>
                          </div>
    
                          <div class="shrink-0 text-right">
                            <div class="flex items-baseline justify-end gap-1">
                              <span class="text-foreground text-lg font-bold tabular-nums sm:text-xl">
                                \${{ plan.employeeCostPerPaycheck }}
                              </span>
                              <span class="text-muted-foreground text-xs font-normal">/ paycheck</span>
                            </div>
                            @if (plan.employerCostPerMonth > 0) {
                              <p class="text-muted-foreground text-xs">
                                Employer pays
                                <span class="text-foreground font-medium tabular-nums"
                                  >\${{ plan.employerCostPerMonth }}/mo</span
                                >
                              </p>
                            } @else {
                              <p class="text-muted-foreground text-xs">No payroll deduction</p>
                            }
                          </div>
                        </div>
    
                        @if (plan.employeeCostPerPaycheck > 0) {
                          <div
                            class="border-border/60 bg-card/60 mt-1 grid grid-cols-2 gap-2.5 rounded-lg border p-3 text-xs sm:grid-cols-4"
                          >
                            <div>
                              <span class="text-muted-foreground block">Annual Maximum</span>
                              <span class="text-foreground font-semibold tabular-nums">{{ plan.annualMax }}</span>
                            </div>
                            <div>
                              <span class="text-muted-foreground block">Preventive Cleanings</span>
                              <span class="text-foreground font-semibold">{{ plan.preventive }}</span>
                            </div>
                            <div>
                              <span class="text-muted-foreground block">Basic Services</span>
                              <span class="text-foreground font-semibold">{{ plan.basic }}</span>
                            </div>
                            <div>
                              <span class="text-muted-foreground block">Major &amp; Orthodontics</span>
                              <span class="text-foreground font-semibold">{{ plan.majorOrOrtho }}</span>
                            </div>
                          </div>
                        }
                      </div>
                    }
                  </ui-radio-group>
                </div>
              </div>
    
              <!-- Category 3: Vision Plan -->
              <div ui-card class="border-border shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex flex-wrap items-center justify-between gap-3 sm:flex-nowrap">
                    <div class="flex items-center gap-2.5">
                      <div
                        class="border-primary/20 bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-lg border"
                      >
                        <lucide-icon [img]="Eye" class="size-4" />
                      </div>
                      <div>
                        <h3 ui-card-title class="text-base sm:text-lg">3. Vision Plan</h3>
                        <p ui-card-description>
                          Routine eye exams, designer frame allowances, contact lenses, and progressive lens discounts.
                        </p>
                      </div>
                    </div>
                    <span ui-badge variant="secondary" class="text-xs"> 2 Plans + Waive </span>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-4">
                  <ui-radio-group [value]="selectedVision()" (valueChange)="selectedVision.set($event)" class="gap-3.5">
                    @for (plan of visionPlans; track plan.id) {
                      <div
                        role="button"
                        tabindex="0"
                        [attr.aria-pressed]="selectedVision() === plan.id"
                        [class]="planCardClass(selectedVision() === plan.id)"
                        (click)="selectedVision.set(plan.id)"
                        (keydown.enter)="selectedVision.set(plan.id)"
                        (keydown.space)="$event.preventDefault(); selectedVision.set(plan.id)"
                      >
                        <div class="flex flex-wrap items-start justify-between gap-3">
                          <div class="flex flex-wrap items-start gap-3">
                            <ui-radio-group-item [id]="plan.id" [value]="plan.id" class="mt-0.5" />
                            <div class="space-y-1">
                              <div class="flex flex-wrap items-center gap-2">
                                <label
                                  [for]="plan.id"
                                  class="text-foreground cursor-pointer text-sm font-semibold sm:text-base"
                                >
                                  {{ plan.name }}
                                </label>
                                @if (plan.badge) {
                                  <span ui-badge [variant]="plan.badgeVariant ?? 'outline'" class="text-xs font-medium">
                                    {{ plan.badge }}
                                  </span>
                                }
                              </div>
                              <p class="text-muted-foreground text-xs">{{ plan.carrier }} · {{ plan.description }}</p>
                            </div>
                          </div>
    
                          <div class="shrink-0 text-right">
                            <div class="flex items-baseline justify-end gap-1">
                              <span class="text-foreground text-lg font-bold tabular-nums sm:text-xl">
                                \${{ plan.employeeCostPerPaycheck }}
                              </span>
                              <span class="text-muted-foreground text-xs font-normal">/ paycheck</span>
                            </div>
                            @if (plan.employerCostPerMonth > 0) {
                              <p class="text-muted-foreground text-xs">
                                Employer pays
                                <span class="text-foreground font-medium tabular-nums"
                                  >\${{ plan.employerCostPerMonth }}/mo</span
                                >
                              </p>
                            } @else {
                              <p class="text-muted-foreground text-xs">No payroll deduction</p>
                            }
                          </div>
                        </div>
    
                        @if (plan.employeeCostPerPaycheck > 0) {
                          <div
                            class="border-border/60 bg-card/60 mt-1 grid grid-cols-1 gap-2.5 rounded-lg border p-3 text-xs sm:grid-cols-3"
                          >
                            <div>
                              <span class="text-muted-foreground block">Annual Exam Copay</span>
                              <span class="text-foreground font-semibold">{{ plan.examCopay }}</span>
                            </div>
                            <div>
                              <span class="text-muted-foreground block">Frame Allowance</span>
                              <span class="text-foreground font-semibold tabular-nums">{{ plan.frameAllowance }}</span>
                            </div>
                            <div>
                              <span class="text-muted-foreground block">Prescription Lenses</span>
                              <span class="text-foreground font-semibold">{{ plan.lenses }}</span>
                            </div>
                          </div>
                        }
                      </div>
                    }
                  </ui-radio-group>
                </div>
              </div>
    
              <!-- Category 4: 401(k) Retirement & Employer Match -->
              <div ui-card class="border-border shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex items-center justify-between">
                    <div class="flex items-center gap-2.5">
                      <div
                        class="border-primary/20 bg-primary/10 text-primary flex size-8 shrink-0 items-center justify-center rounded-lg border"
                      >
                        <lucide-icon [img]="PiggyBank" class="size-4" />
                      </div>
                      <div>
                        <h3 ui-card-title class="text-base sm:text-lg">4. 401(k) Retirement &amp; Employer Match</h3>
                        <p ui-card-description>Pre-tax salary deferrals with tiered 100% + 50% company matching formula.</p>
                      </div>
                    </div>
                    <span ui-badge [variant]="maxMatchUnlocked() ? 'default' : 'outline'" class="text-xs">
                      {{ maxMatchUnlocked() ? 'Max Match Active' : 'Match Available' }}
                    </span>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-6">
                  <!-- Employer Match Callout Box -->
                  <div
                    class="border-primary/30 bg-primary/5 dark:bg-primary/10 flex flex-col gap-3 rounded-xl border p-4 sm:flex-row sm:items-center sm:justify-between"
                  >
                    <div class="flex flex-wrap items-start gap-3">
                      <lucide-icon [img]="Percent" class="text-primary mt-0.5 size-5 shrink-0" />
                      <div class="space-y-1">
                        <span class="text-foreground text-sm font-semibold">Company Match Formula</span>
                        <p class="text-muted-foreground text-xs leading-relaxed">
                          100% match up to 4% + 50% match on next 2% ·
                          <strong class="text-foreground font-medium">Maximum $6,000 employer match unlocked!</strong>
                        </p>
                      </div>
                    </div>
    
                    <div class="shrink-0">
                      <span
                        ui-badge
                        [variant]="maxMatchUnlocked() ? 'secondary' : 'outline'"
                        [class]="matchBadgeClass()"
                        class="gap-1.5 px-3 py-1 text-xs font-semibold"
                      >
                        @if (maxMatchUnlocked()) {
                          <lucide-icon [img]="CheckCircle2" class="size-3.5" />
                          100% Max Match Achieved ($6,000/yr)
                        } @else {
                          <lucide-icon [img]="AlertCircle" class="size-3.5" />
                          Leaving \${{ missedMatchAnnual().toLocaleString('en-US') }}/yr on table
                        }
                      </span>
                    </div>
                  </div>
    
                  <!-- Interactive Slider Section -->
                  <div class="space-y-4">
                    <div class="flex items-center justify-between">
                      <div class="space-y-0.5">
                        <span class="text-foreground text-sm font-semibold">Your Pre-Tax Contribution Rate</span>
                        <p class="text-muted-foreground text-xs">
                          Calculated from gross salary (\${{
                            paycheckGross().toLocaleString('en-US', {
                              minimumFractionDigits: 2,
                              maximumFractionDigits: 2,
                            })
                          }}
                          / semi-monthly paycheck)
                        </p>
                      </div>
    
                      <div class="text-right">
                        <div class="flex items-baseline justify-end gap-1">
                          <span class="text-primary text-2xl font-bold tabular-nums sm:text-3xl"> {{ k401Rate() }}% </span>
                          <span class="text-muted-foreground text-xs">Contribution</span>
                        </div>
                        <span class="text-foreground text-xs font-medium tabular-nums">
                          \${{ k401EmployeePerPaycheck().toFixed(2) }} / paycheck (\${{
                            k401EmployeeAnnual().toLocaleString('en-US')
                          }}/yr)
                        </span>
                      </div>
                    </div>
    
                    <div class="py-5">
                      <ui-slider
                        [value]="[k401Rate()]"
                        (valueChange)="onK401Change($event)"
                        [min]="1"
                        [max]="20"
                        [step]="1"
                        [marks]="sliderMarks"
                        [tooltip]="k401Tooltip"
                      />
                    </div>
                  </div>
    
                  <!-- 401(k) Financial Impact Breakdown -->
                  <div class="grid grid-cols-1 gap-3 sm:grid-cols-3">
                    <div class="border-border bg-card/60 rounded-lg border p-3 text-center sm:text-left">
                      <span class="text-muted-foreground block text-xs">Your Paycheck Deferral</span>
                      <span class="text-foreground text-lg font-bold tabular-nums">
                        \${{ k401EmployeePerPaycheck().toFixed(2) }}
                      </span>
                      <span class="text-muted-foreground block text-xs tabular-nums">
                        \${{ k401EmployeeAnnual().toLocaleString('en-US') }} / year
                      </span>
                    </div>
    
                    <div class="border-success/30 bg-success/5 rounded-lg border p-3 text-center sm:text-left">
                      <span class="text-success block text-xs font-medium">Employer Match Added</span>
                      <span class="text-success text-lg font-bold tabular-nums">
                        +\${{ k401EmployerPerPaycheck().toFixed(2) }}
                      </span>
                      <span class="text-muted-foreground block text-xs tabular-nums">
                        \${{ k401EmployerAnnual().toLocaleString('en-US') }} / year (Free Match)
                      </span>
                    </div>
    
                    <div class="border-border bg-card/60 rounded-lg border p-3 text-center sm:text-left">
                      <span class="text-muted-foreground block text-xs">Total 401(k) Annual Savings</span>
                      <span class="text-foreground text-lg font-bold tabular-nums">
                        \${{ (k401EmployeeAnnual() + k401EmployerAnnual()).toLocaleString('en-US') }}
                      </span>
                      <span class="text-muted-foreground block text-xs"> 2026 IRS Cap: $23,500 </span>
                    </div>
                  </div>
                </div>
              </div>
            </div>
    
            <!-- Sticky Paycheck Impact Summary Box (Col 4) -->
            <div class="lg:sticky lg:top-8 lg:col-span-4">
              <div ui-card class="border-border bg-card shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground text-xs font-semibold tracking-wider uppercase">
                      Paycheck Impact Summary
                    </span>
                    <span ui-badge variant="outline" class="text-xs"> Semi-Monthly </span>
                  </div>
    
                  <!-- Primary Highlight Metric 1: Total Employee Cost per Paycheck -->
                  <div class="mt-4 space-y-1">
                    <span class="text-muted-foreground text-xs font-medium">Total Employee Benefit Cost</span>
                    <div class="flex items-baseline gap-1.5">
                      <span class="text-foreground text-4xl font-bold tracking-tight tabular-nums sm:text-5xl">
                        \${{ healthCostPerPaycheck().toFixed(2) }}
                      </span>
                      <span class="text-muted-foreground text-sm font-normal"> / pay period</span>
                    </div>
                    <p class="text-muted-foreground text-xs">Pre-tax health, dental, and vision deductions</p>
                  </div>
    
                  <!-- Primary Highlight Metric 2: Total Annual Employer Benefit Value -->
                  <div class="border-primary/20 bg-primary/5 dark:bg-primary/10 mt-4 rounded-xl border p-3.5">
                    <span class="text-muted-foreground block text-xs font-medium">Total Annual Employer Value</span>
                    <div class="flex items-baseline gap-1">
                      <span class="text-primary text-2xl font-bold tracking-tight tabular-nums sm:text-3xl">
                        \${{
                          totalEmployerAnnualValue().toLocaleString('en-US', {
                            minimumFractionDigits: 2,
                            maximumFractionDigits: 2,
                          })
                        }}
                      </span>
                      <span class="text-muted-foreground text-xs font-normal"> / year</span>
                    </div>
                    <p class="text-muted-foreground mt-1 text-xs">
                      Includes company medical, dental, vision subsidies, HSA seed, match &amp; insurance.
                    </p>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-4 pt-0">
                  <ui-separator />
    
                  <!-- Itemized Paycheck Deductions -->
                  <div class="space-y-2 text-xs">
                    <span class="text-muted-foreground block font-semibold tracking-wider uppercase">
                      Employee Payroll Deductions
                    </span>
    
                    <div class="flex items-center justify-between">
                      <span class="text-foreground"
                        >Medical ({{ currentMedical().name.split(' ')[0] }} {{ currentMedical().name.split(' ')[1] }})</span
                      >
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ currentMedical().employeeCostPerPaycheck.toFixed(2) }}</span
                      >
                    </div>
    
                    <div class="flex items-center justify-between">
                      <span class="text-foreground"
                        >Dental ({{ currentDental().name.split(' ')[0] }} {{ currentDental().name.split(' ')[1] }})</span
                      >
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ currentDental().employeeCostPerPaycheck.toFixed(2) }}</span
                      >
                    </div>
    
                    <div class="flex items-center justify-between">
                      <span class="text-foreground"
                        >Vision ({{ currentVision().name.split(' ')[0] }} {{ currentVision().name.split(' ')[1] }})</span
                      >
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ currentVision().employeeCostPerPaycheck.toFixed(2) }}</span
                      >
                    </div>
    
                    <div class="border-border/60 flex items-center justify-between border-t pt-1.5 font-semibold">
                      <span class="text-foreground">Pre-Tax Health Total</span>
                      <span class="text-foreground tabular-nums">\${{ healthCostPerPaycheck().toFixed(2) }}</span>
                    </div>
    
                    <div class="text-muted-foreground flex items-center justify-between">
                      <span>401(k) Contribution ({{ k401Rate() }}%)</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ k401EmployeePerPaycheck().toFixed(2) }}</span
                      >
                    </div>
    
                    <div class="bg-muted/50 flex items-center justify-between rounded-md p-2 font-semibold">
                      <span class="text-foreground">Total Pre-Tax per Paycheck</span>
                      <span class="text-foreground tabular-nums">\${{ totalEmployeePerPaycheck().toFixed(2) }}</span>
                    </div>
    
                    <div class="border-border/60 text-muted-foreground flex items-center justify-between border-t pt-1">
                      <span>Est. Pre-Tax Tax Savings (~25%)</span>
                      <span class="text-success font-medium tabular-nums"
                        >-\${{ estimatedTaxSavingsPerPaycheck().toFixed(2) }}</span
                      >
                    </div>
    
                    <div class="text-muted-foreground flex items-center justify-between">
                      <span>Est. Net Take-Home Impact</span>
                      <span class="text-foreground font-medium tabular-nums">-\${{ netTakeHomeImpact().toFixed(2) }}</span>
                    </div>
                  </div>
    
                  <ui-separator />
    
                  <!-- Itemized Employer Annual Contributions -->
                  <div class="space-y-1.5 text-xs">
                    <span class="text-muted-foreground block font-semibold tracking-wider uppercase">
                      Employer Benefits Breakdown
                    </span>
    
                    <div class="flex items-center justify-between">
                      <span class="text-muted-foreground">Medical Subsidy</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ (currentMedical().employerCostPerMonth * 12).toLocaleString('en-US') }}/yr</span
                      >
                    </div>
    
                    <div class="flex items-center justify-between">
                      <span class="text-muted-foreground">Dental Subsidy</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ (currentDental().employerCostPerMonth * 12).toLocaleString('en-US') }}/yr</span
                      >
                    </div>
    
                    <div class="flex items-center justify-between">
                      <span class="text-muted-foreground">Vision Subsidy</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ (currentVision().employerCostPerMonth * 12).toLocaleString('en-US') }}/yr</span
                      >
                    </div>
    
                    @if (currentMedical().hsaSeed > 0) {
                      <div class="flex items-center justify-between">
                        <span class="text-muted-foreground">HSA Annual Contribution</span>
                        <span class="text-foreground font-medium tabular-nums"
                          >\${{ currentMedical().hsaSeed.toLocaleString('en-US') }}/yr</span
                        >
                      </div>
                    }
    
                    <div class="flex items-center justify-between">
                      <span class="text-muted-foreground">401(k) Employer Match</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ k401EmployerAnnual().toLocaleString('en-US') }}/yr</span
                      >
                    </div>
    
                    <div class="flex items-center justify-between">
                      <span class="text-muted-foreground">Life, AD&amp;D &amp; Disability</span>
                      <span class="text-foreground font-medium tabular-nums"
                        >\${{ employerLifeDisabilityAnnual.toLocaleString('en-US') }}/yr</span
                      >
                    </div>
                  </div>
                </div>
    
                <div ui-card-footer class="flex flex-col gap-2.5 pt-0">
                  @if (!isSubmitted()) {
                    <button
                      ui-button
                      size="lg"
                      class="w-full gap-2 font-semibold shadow-xs"
                      (click)="showSignModal.set(true)"
                    >
                      <lucide-icon [img]="FileSignature" class="size-4" />
                      Save Selections &amp; Sign
                    </button>
                  } @else {
                    <button
                      ui-button
                      variant="outline"
                      size="default"
                      class="border-success/30 bg-success/10 text-success w-full gap-2 font-semibold"
                      (click)="handleResetEnrollment()"
                    >
                      <lucide-icon [img]="Check" class="size-4" />
                      Elections Signed (Edit)
                    </button>
                  }
    
                  <p class="text-muted-foreground text-center text-xs">
                    Annual elections lock on {{ deadlineDate }}, 11:59 PM EST
                  </p>
                </div>
              </div>
            </div>
          </div>
    
          <!-- Electronic Signature Confirmation Modal Dialog -->
          @if (showSignModal()) {
            <div class="bg-background/80 fixed inset-0 z-50 flex items-center justify-center p-4 backdrop-blur-xs">
              <div
                class="border-border bg-card animate-in fade-in zoom-in-95 relative w-full max-w-lg rounded-xl border p-6 shadow-xl duration-150"
              >
                <div class="space-y-2">
                  <div class="text-primary flex items-center gap-2">
                    <lucide-icon [img]="FileSignature" class="size-5" />
                    <h3 class="text-foreground text-lg font-bold">Review &amp; Sign Elective Enrollment</h3>
                  </div>
                  <p class="text-muted-foreground text-xs">
                    Please verify your selections below before electronically signing for the 2026-2027 plan year.
                  </p>
                </div>
    
                <div class="border-border bg-muted/40 my-4 space-y-2 rounded-lg border p-3.5 text-xs">
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground">Employee:</span>
                    <span class="text-foreground font-medium">{{ employeeName }} ({{ coverageTier }})</span>
                  </div>
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground">Medical Plan:</span>
                    <span class="text-foreground font-medium">{{ currentMedical().name }}</span>
                  </div>
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground">Dental Plan:</span>
                    <span class="text-foreground font-medium">{{ currentDental().name }}</span>
                  </div>
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground">Vision Plan:</span>
                    <span class="text-foreground font-medium">{{ currentVision().name }}</span>
                  </div>
                  <div class="flex items-center justify-between">
                    <span class="text-muted-foreground">401(k) Contribution:</span>
                    <span class="text-foreground font-medium tabular-nums"
                      >{{ k401Rate() }}% (\${{ k401EmployeePerPaycheck().toFixed(2) }} / paycheck)</span
                    >
                  </div>
                  <div class="border-border/60 flex items-center justify-between border-t pt-2 font-bold">
                    <span class="text-foreground">Total Deduction per Paycheck:</span>
                    <span class="text-foreground tabular-nums">\${{ totalEmployeePerPaycheck().toFixed(2) }}</span>
                  </div>
                </div>
    
                <div class="space-y-3">
                  <label class="flex cursor-pointer items-start gap-2.5 select-none">
                    <input
                      type="checkbox"
                      [checked]="signatureAcknowledged()"
                      (change)="signatureAcknowledged.set($any($event.target).checked)"
                      class="border-input text-primary focus-visible:ring-ring mt-0.5 size-4 rounded border focus-visible:ring-2"
                    />
                    <span class="text-muted-foreground text-xs leading-relaxed">
                      I acknowledge that I have selected the benefit plans above and authorize pre-tax semi-monthly payroll
                      deductions commencing October 1, 2026.
                    </span>
                  </label>
                </div>
    
                <div class="mt-6 flex items-center justify-end gap-2.5">
                  <button ui-button variant="outline" size="sm" (click)="showSignModal.set(false)">Cancel</button>
                  <button
                    ui-button
                    size="sm"
                    [disabled]="!signatureAcknowledged()"
                    class="gap-1.5 font-semibold"
                    (click)="handleSignAndSubmit()"
                  >
                    <lucide-icon [img]="FileCheck" class="size-4" />
                    Confirm &amp; Submit Signature
                  </button>
                </div>
              </div>
            </div>
          }
        </div>
      `,
    })
    export class UiBenefitsEnrollmentPortalComponent implements OnInit {
      protected readonly AlertCircle = AlertCircle
      protected readonly Check = Check
      protected readonly CheckCircle2 = CheckCircle2
      protected readonly Clock = Clock
      protected readonly Download = Download
      protected readonly Eye = Eye
      protected readonly FileCheck = FileCheck
      protected readonly FileSignature = FileSignature
      protected readonly HeartPulse = HeartPulse
      protected readonly Percent = Percent
      protected readonly PiggyBank = PiggyBank
      protected readonly RefreshCw = RefreshCw
      protected readonly ShieldCheck = ShieldCheck
      protected readonly User = User
      protected readonly Users = Users
    
      protected readonly medicalPlans = MEDICAL_PLANS
      protected readonly dentalPlans = DENTAL_PLANS
      protected readonly visionPlans = VISION_PLANS
      protected readonly sliderMarks = SLIDER_MARKS
      protected readonly employerLifeDisabilityAnnual = 2386
    
      @Input() employeeName = 'Elena Rostova'
      @Input() employeeId = 'EMP-48201'
      @Input() coverageTier = 'Employee + Spouse'
      @Input() department = 'Engineering · Senior Staff'
      @Input() deadlineDate = 'Sep 15'
      @Input() daysRemaining = 14
      @Input() annualSalary = 120000
      @Input() payPeriodsPerYear = 24
      @Input() initialMedicalPlan = 'medical-ppo-hsa'
      @Input() initialDentalPlan = 'dental-comprehensive'
      @Input() initialVisionPlan = 'vision-choice-plus'
      @Input() initial401kRate = 6
      @Input('class') className?: string
    
      readonly selectedMedical = signal('medical-ppo-hsa')
      readonly selectedDental = signal('dental-comprehensive')
      readonly selectedVision = signal('vision-choice-plus')
      readonly k401Rate = signal(6)
      readonly isSubmitted = signal(false)
      readonly signatureAcknowledged = signal(false)
      readonly showSignModal = signal(false)
    
      ngOnInit(): void {
        this.selectedMedical.set(this.initialMedicalPlan)
        this.selectedDental.set(this.initialDentalPlan)
        this.selectedVision.set(this.initialVisionPlan)
        this.k401Rate.set(this.initial401kRate)
      }
    
      readonly currentMedical = computed(
        () => MEDICAL_PLANS.find((p) => p.id === this.selectedMedical()) ?? MEDICAL_PLANS[0]!,
      )
      readonly currentDental = computed(() => DENTAL_PLANS.find((p) => p.id === this.selectedDental()) ?? DENTAL_PLANS[0]!)
      readonly currentVision = computed(() => VISION_PLANS.find((p) => p.id === this.selectedVision()) ?? VISION_PLANS[0]!)
    
      readonly paycheckGross = computed(() => this.annualSalary / this.payPeriodsPerYear)
    
      readonly k401EmployeePerPaycheck = computed(() => (this.paycheckGross() * this.k401Rate()) / 100)
      readonly k401EmployeeAnnual = computed(() => this.k401EmployeePerPaycheck() * this.payPeriodsPerYear)
    
      // 100% match up to 4% + 50% match on next 2% -> max 5.0% at a 6% employee contribution.
      readonly employerMatchRate = computed(() => {
        const rate = this.k401Rate()
        if (rate <= 0) return 0
        if (rate <= 4) return rate
        if (rate === 5) return 4.5
        return 5.0
      })
    
      readonly k401EmployerPerPaycheck = computed(() => (this.paycheckGross() * this.employerMatchRate()) / 100)
      readonly k401EmployerAnnual = computed(() => this.k401EmployerPerPaycheck() * this.payPeriodsPerYear)
      readonly maxMatchUnlocked = computed(() => this.k401Rate() >= 6)
      readonly missedMatchAnnual = computed(() => {
        const maxPossible = (this.annualSalary * 5.0) / 100
        return Math.max(0, maxPossible - this.k401EmployerAnnual())
      })
    
      readonly healthCostPerPaycheck = computed(
        () =>
          this.currentMedical().employeeCostPerPaycheck +
          this.currentDental().employeeCostPerPaycheck +
          this.currentVision().employeeCostPerPaycheck,
      )
    
      readonly totalEmployeePerPaycheck = computed(() => this.healthCostPerPaycheck() + this.k401EmployeePerPaycheck())
      readonly estimatedTaxSavingsPerPaycheck = computed(
        () => Math.round(this.totalEmployeePerPaycheck() * 0.25 * 100) / 100,
      )
      readonly netTakeHomeImpact = computed(() => this.totalEmployeePerPaycheck() - this.estimatedTaxSavingsPerPaycheck())
    
      readonly totalEmployerAnnualValue = computed(
        () =>
          this.currentMedical().employerCostPerMonth * 12 +
          this.currentDental().employerCostPerMonth * 12 +
          this.currentVision().employerCostPerMonth * 12 +
          this.currentMedical().hsaSeed +
          this.k401EmployerAnnual() +
          this.employerLifeDisabilityAnnual,
      )
    
      get rootClass(): string {
        return cn('mx-auto w-full max-w-6xl space-y-8 p-4 sm:p-6 lg:p-8', this.className)
      }
    
      planCardClass(selected: boolean): string {
        return cn(
          'focus-visible:ring-ring relative flex cursor-pointer flex-col gap-3 rounded-xl border p-4.5 transition-colors duration-150 focus-visible:ring-2 focus-visible:outline-none',
          selected
            ? 'border-primary bg-primary/[0.03] dark:bg-primary/10 ring-primary/30 shadow-xs ring-1'
            : 'border-border hover:border-border/80 hover:bg-muted/30',
        )
      }
    
      matchBadgeClass(): string {
        return cn(
          this.maxMatchUnlocked()
            ? 'border-success/30 bg-success/10 text-success'
            : 'border-warning/30 bg-warning/10 text-warning',
        )
      }
    
      readonly k401Tooltip = (val: number): string =>
        `${val}% (${((this.annualSalary * val) / 100).toLocaleString('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 })}/yr)`
    
      onK401Change(value: number[]): void {
        if (value.length > 0) this.k401Rate.set(value[0]!)
      }
    
      handleSignAndSubmit(): void {
        if (!this.signatureAcknowledged()) return
        this.isSubmitted.set(true)
        this.showSignModal.set(false)
      }
    
      handleResetEnrollment(): void {
        this.isSubmitted.set(false)
        this.signatureAcknowledged.set(false)
      }
    }
    
  • src/app/components/blocks/benefits-enrollment-portal/index.ts0.2 kB

Raw manifest:https://uipkge.dev/r/angular/benefits-enrollment-portal.json