html
<!-- Calculator -->
<div id="calculatorContainer" class="calculator-container bg-white rounded-xl overflow-hidden">
<!-- Input Section -->
<div class="bg-gradient-to-r from-navy to-teal p-6 text-white">
<h2 class="text-xl font-bold mb-4 font-quicksand">Enter Employee Details</h2>
<div class="flex flex-col sm:flex-row gap-4">
<div class="flex-1">
<label for="baseSalary" class="block text-sm font-medium mb-1 font-montserrat">Base Monthly Salary (USD)</label>
<div class="relative">
<span class="absolute inset-y-0 left-0 pl-3 flex items-center text-white/80">$</span>
<input type="number" id="baseSalary" class="w-full bg-white/20 border border-white/30 rounded-lg py-2 pl-8 pr-3 text-white placeholder-white/60 focus:border-white font-montserrat" placeholder="Enter amount" value="1500">
</div>
</div>
</div>
</div>
<!-- Results Section -->
<div class="p-6 font-montserrat">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Left Column -->
<div>
<h3 class="text-lg font-bold text-navy mb-4 font-quicksand">Monthly EOR Contributions</h3>
<div class="space-y-3">
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600 flex items-center">
IHSS (Health) - 5%
<div class="tooltip ml-1">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="tooltiptext">Capped at $480</span>
</div>
</span>
<span id="ihssHealth" class="font-medium">$24.00</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600 flex items-center">
IHSS (Disability/Old Age) - 4%
<div class="tooltip ml-1">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="tooltiptext">Capped at $480</span>
</div>
</span>
<span id="ihssDisability" class="font-medium">$19.20</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600">RAP - Severance Reserve - 4%</span>
<span id="rapSeverance" class="font-medium">$60.00</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600">RAP - Pension - 1.5%</span>
<span id="rapPension" class="font-medium">$22.50</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600">INFOP - 1%</span>
<span id="infop" class="font-medium">$15.00</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600">13th & 14th Month Bonus - 16.67%</span>
<span id="bonuses" class="font-medium">$250.05</span>
</div>
<div class="bg-navy/5 p-3 rounded-lg mt-2">
<div class="flex justify-between font-semibold">
<span class="text-navy font-quicksand">EOR Contributions Subtotal</span>
<span id="contributionsSubtotal" class="text-navy">$390.75</span>
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div>
<h3 class="text-lg font-bold text-navy mb-4 font-quicksand">Monthly Escrow Reserves</h3>
<div class="space-y-3">
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600 flex items-center">
Vacation Accrual
<div class="tooltip ml-1">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="tooltiptext">10 days per year (Daily salary = Base salary ÷ 30)</span>
</div>
</span>
<span id="vacationEscrow" class="font-medium">$41.67</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600 flex items-center">
Notice Provision
<div class="tooltip ml-1">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="tooltiptext">14 days per year (Daily salary = Base salary ÷ 30)</span>
</div>
</span>
<span id="noticeEscrow" class="font-medium">$58.33</span>
</div>
<div class="bg-navy/5 p-3 rounded-lg mt-2">
<div class="flex justify-between font-semibold">
<span class="text-navy font-quicksand">Monthly Escrow Subtotal</span>
<span id="escrowSubtotal" class="text-navy">$100.00</span>
</div>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100 mt-4">
<span class="text-gray-600">Base Salary</span>
<span id="baseSalaryDisplay" class="font-medium">$1,500.00</span>
</div>
<div class="result-row flex justify-between p-2 border-b border-gray-100">
<span class="text-gray-600">WIND HR Monthly Service Fee</span>
<span id="serviceFee" class="font-medium">$300.00</span>
</div>
</div>
</div>
</div>
<!-- Total Section -->
<div class="mt-8 bg-gradient-to-r from-teal/10 to-coral/10 p-4 rounded-lg border border-teal/20">
<div class="flex flex-col sm:flex-row justify-between items-center">
<span class="text-lg font-bold text-navy mb-2 sm:mb-0 font-quicksand">Final Total Monthly Cost</span>
<div class="text-right">
<div id="totalCost" class="text-2xl font-bold text-teal font-quicksand">$2,290.75</div>
</div>
</div>
</div>
<!-- Action Buttons -->
<div class="mt-6 flex flex-col sm:flex-row gap-3 justify-end">
<button id="downloadPdf" class="px-4 py-2 bg-white border border-gray-300 rounded-lg text-navy font-medium hover:bg-gray-50 transition-colors flex items-center justify-center font-quicksand">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2 text-navy" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
Download as PDF
</button>
<button id="requestQuote" class="px-4 py-2 bg-coral rounded-lg text-white font-medium hover:bg-coral/90 transition-colors flex items-center justify-center font-quicksand">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
Request Formal Quote
</button>
</div>
</div>
</div>
<!-- Footer -->
<div class="mt-8 text-center">
<div class="flex justify-center items-center mb-3">
<div class="h-8 w-8 rounded-full bg-navy flex items-center justify-center text-white font-bold mr-2 font-quicksand">W</div>
<span class="text-navy font-bold font-quicksand">WIND HR</span>
</div>
<p class="text-sm text-gray-500 font-montserrat">© 2025 WIND HR. All calculations are estimates and may vary based on specific circumstances.</p>
</div>
</div>
</div>
<!-- Email Request Modal -->
<div id="emailModal" class="modal">
<div class="modal-content">
<span class="close-modal">×</span>
<h2 class="text-xl font-bold text-navy mb-4 font-quicksand">Request Formal Quote</h2>
<form id="quoteForm" class="space-y-4">
<div>
<label for="name" class="block text-sm font-medium mb-1 font-montserrat">Your Name</label>
<input type="text" id="name" class="w-full border border-gray-300 rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-teal/50" required>
</div>
<div>
<label for="email" class="block text-sm font-medium mb-1 font-montserrat">Your Email</label>
<input type="email" id="email" class="w-full border border-gray-300 rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-teal/50" required>
</div>
<div>
<label for="company" class="block text-sm font-medium mb-1 font-montserrat">Company Name</label>
<input type="text" id="company" class="w-full border border-gray-300 rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-teal/50" required>
</div>
<div>
<label for="message" class="block text-sm font-medium mb-1 font-montserrat">Additional Information</label>
<textarea id="message" rows="3" class="w-full border border-gray-300 rounded-lg py-2 px-3 focus:outline-none focus:ring-2 focus:ring-teal/50"></textarea>
</div>
<div class="flex justify-end">
<button type="submit" class="px-4 py-2 bg-coral rounded-lg text-white font-medium hover:bg-coral/90 transition-colors font-quicksand">Send Request</button>
</div>
</form>
</div>
</div>
<!-- Hidden div for PDF generation -->
<div id="pdfContent">
<!-- This will be populated with content for PDF generation -->
</div>
<script>
// Make jsPDF available in the global scope
window.jspdf = window.jspdf || {};
// Get DOM elements
const baseSalaryInput = document.getElementById('baseSalary');
const baseSalaryDisplay = document.getElementById('baseSalaryDisplay');
const ihssHealth = document.getElementById('ihssHealth');
const ihssDisability = document.getElementById('ihssDisability');
const rapSeverance = document.getElementById('rapSeverance');
const rapPension = document.getElementById('rapPension');
const infop = document.getElementById('infop');
const bonuses = document.getElementById('bonuses');
const vacationEscrow = document.getElementById('vacationEscrow');
const noticeEscrow = document.getElementById('noticeEscrow');
const contributionsSubtotal = document.getElementById('contributionsSubtotal');
const escrowSubtotal = document.getElementById('escrowSubtotal');
const totalCost = document.getElementById('totalCost');
const serviceFee = document.getElementById('serviceFee');
const downloadPdfBtn = document.getElementById('downloadPdf');
const requestQuoteBtn = document.getElementById('requestQuote');
const emailModal = document.getElementById('emailModal');
const closeModal = document.querySelector('.close-modal');
const quoteForm = document.getElementById('quoteForm');
const pdfContent = document.getElementById('pdfContent');
// Format currency function
function formatCurrency(amount) {
return `$${amount.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',')}`;
}
// Calculate all values
function calculateValues() {
const baseSalary = parseFloat(baseSalaryInput.value) || 0;
// Calculate contributions with caps
const healthContributionUncapped = baseSalary * 0.05;
const healthContribution = Math.min(healthContributionUncapped, 24); // 5% of $480 cap = $24
const disabilityContributionUncapped = baseSalary * 0.04;
const disabilityContribution = Math.min(disabilityContributionUncapped, 19.2); // 4% of $480 cap = $19.20
const severanceReserve = baseSalary * 0.04;
const pensionContribution = baseSalary * 0.015;
const infopContribution = baseSalary * 0.01;
const monthlyBonuses = baseSalary * 0.1667;
// Calculate monthly escrow amounts using the correct formula
const dailySalary = baseSalary / 30;
// Vacation: 10 days per year, divided by 12 for monthly amount
const annualVacationEscrow = dailySalary * 10;
const monthlyVacationEscrow = annualVacationEscrow / 12;
// Notice: 14 days per year, divided by 12 for monthly amount
const annualNoticeEscrow = dailySalary * 14;
const monthlyNoticeEscrow = annualNoticeEscrow / 12;
const monthlyEscrowTotal = monthlyVacationEscrow + monthlyNoticeEscrow;
// Calculate subtotals
const contributionsTotal = healthContribution + disabilityContribution + severanceReserve +
pensionContribution + infopContribution + monthlyBonuses;
// Service fee
const serviceFeeAmount = 300;
// Calculate final total (monthly)
const total = baseSalary + contributionsTotal + monthlyEscrowTotal + serviceFeeAmount;
// Update DOM
baseSalaryDisplay.textContent = formatCurrency(baseSalary);
ihssHealth.textContent = formatCurrency(healthContribution);
ihssDisability.textContent = formatCurrency(disabilityContribution);
rapSeverance.textContent = formatCurrency(severanceReserve);
rapPension.textContent = formatCurrency(pensionContribution);
infop.textContent = formatCurrency(infopContribution);
bonuses.textContent = formatCurrency(monthlyBonuses);
vacationEscrow.textContent = formatCurrency(monthlyVacationEscrow);
noticeEscrow.textContent = formatCurrency(monthlyNoticeEscrow);
contributionsSubtotal.textContent = formatCurrency(contributionsTotal);
escrowSubtotal.textContent = formatCurrency(monthlyEscrowTotal);
serviceFee.textContent = formatCurrency(serviceFeeAmount);
totalCost.textContent = formatCurrency(total);
return {
baseSalary,
healthContribution,
disabilityContribution,
severanceReserve,
pensionContribution,
infopContribution,
monthlyBonuses,
monthlyVacationEscrow,
monthlyNoticeEscrow,
contributionsTotal,
monthlyEscrowTotal,
serviceFeeAmount,
total
};
}
// Generate PDF content
function generatePdfContent(data) {
const date = new Date().toLocaleDateString();
return `
<div style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px;">
<div style="text-align: center; margin-bottom: 20px;">
<h1 style="color: #033E54; margin-bottom: 5px;">WIND HR EOR Pricing Estimate</h1>
<p style="color: #666;">Generated on ${date}</p>
</div>
<div style="margin-bottom: 20px;">
<h2 style="color: #033E54; border-bottom: 1px solid #eee; padding-bottom: 10px;">Employee Cost Summary</h2>
<p><strong>Base Monthly Salary:</strong> ${formatCurrency(data.baseSalary)}</p>
</div>
<div style="display: flex; margin-bottom: 20px;">
<div style="flex: 1; margin-right: 20px;">
<h3 style="color: #033E54;">Monthly EOR Contributions</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">IHSS (Health) - 5%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.healthContribution)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">IHSS (Disability/Old Age) - 4%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.disabilityContribution)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">RAP - Severance Reserve - 4%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.severanceReserve)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">RAP - Pension - 1.5%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.pensionContribution)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">INFOP - 1%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.infopContribution)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">13th & 14th Month Bonus - 16.67%</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.monthlyBonuses)}</td>
</tr>
<tr style="background-color: #f5f5f5;">
<td style="padding: 8px 0;"><strong>EOR Contributions Subtotal</strong></td>
<td style="text-align: right; padding: 8px 0;"><strong>${formatCurrency(data.contributionsTotal)}</strong></td>
</tr>
</table>
</div>
<div style="flex: 1;">
<h3 style="color: #033E54;">Monthly Escrow Reserves</h3>
<table style="width: 100%; border-collapse: collapse;">
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">Vacation Accrual</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.monthlyVacationEscrow)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">Notice Provision</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.monthlyNoticeEscrow)}</td>
</tr>
<tr style="background-color: #f5f5f5;">
<td style="padding: 8px 0;"><strong>Monthly Escrow Subtotal</strong></td>
<td style="text-align: right; padding: 8px 0;"><strong>${formatCurrency(data.monthlyEscrowTotal)}</strong></td>
</tr>
</table>
<div style="margin-top: 20px;">
<table style="width: 100%; border-collapse: collapse;">
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">Base Salary</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.baseSalary)}</td>
</tr>
<tr style="border-bottom: 1px solid #eee;">
<td style="padding: 8px 0;">WIND HR Monthly Service Fee</td>
<td style="text-align: right; padding: 8px 0;">${formatCurrency(data.serviceFeeAmount)}</td>
</tr>
</table>
</div>
</div>
</div>
<div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; margin-top: 20px;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<span style="font-size: 18px; font-weight: bold; color: #033E54;">Final Total Monthly Cost</span>
<span style="font-size: 24px; font-weight: bold; color: #00968A;">${formatCurrency(data.total)}</span>
</div>
</div>
<div style="margin-top: 30px; text-align: center; color: #666; font-size: 12px;">
<p>This is an estimate provided by WIND HR's EOR Pricing Calculator.</p>
<p>For a formal quote, please contact finance@wind-hr.com</p>
<p>© 2025 WIND HR. All calculations are estimates and may vary based on specific circumstances.</p>
</div>
</div>
`;
}
// Generate and download PDF
async function generatePDF() {
const data = calculateValues();
// Set content for PDF generation
pdfContent.innerHTML = generatePdfContent(data);
try {
// Use html2canvas to capture the content
const canvas = await html2canvas(pdfContent, {
scale: 2, // Higher scale for better quality
logging: false,
useCORS: true
});
// Initialize jsPDF
const { jsPDF } = window.jspdf;
const pdf = new jsPDF('p', 'mm', 'a4');
// Calculate dimensions
const imgWidth = 210; // A4 width in mm
const imgHeight = canvas.height * imgWidth / canvas.width;
// Add the image to the PDF
const imgData = canvas.toDataURL('image/png');
pdf.addImage(imgData, 'PNG', 0, 0, imgWidth, imgHeight);
// Download the PDF
pdf.save('WIND_HR_EOR_Pricing_Estimate.pdf');
return pdf;
} catch (error) {
console.error('Error generating PDF:', error);
alert('There was an error generating the PDF. Please try again.');
return null;
}
}
// Modal functions
function openModal() {
emailModal.style.display = 'block';
}
function closeModalFunc() {
emailModal.style.display = 'none';
}
// Event listeners
baseSalaryInput.addEventListener('input', calculateValues);
downloadPdfBtn.addEventListener('click', function() {
generatePDF();
});
requestQuoteBtn.addEventListener('click', function() {
openModal();
});
closeModal.addEventListener('click', closeModalFunc);
window.addEventListener('click', function(event) {
if (event.target === emailModal) {
closeModalFunc();
}
});
quoteForm.addEventListener('submit', async function(e) {
e.preventDefault();
const name = document.getElementById('name').value;
const email = document.getElementById('email').value;
const company = document.getElementById('company').value;
const message = document.getElementById('message').value;
// Generate PDF
const pdf = await generatePDF();
if (pdf) {
// In a real implementation, you would send the form data and PDF to a server
// Here we'll simulate the email being sent to finance@wind-hr.com
alert(`Thank you, ${name}! Your quote request has been sent to finance@wind-hr.com.\n\nA PDF with your calculation has been generated and would be attached to the email in a real implementation.`);
closeModalFunc();
quoteForm.reset();
}
});
// Initial calculation
calculateValues();
</script>