Enter Your Tax Information (2025 Tax Year)
Your total income before deductions.
Gains from assets held over 1 year.
Eligible dividends taxed at capital gains rates.
Adjustments to income (above-the-line).
Your Tax Analysis (2025 Tax Year)
Income Breakdown by Tax Bracket
2025 Federal Income Tax Brackets (Estimated)
These are estimated tax brackets for the 2025 tax year, for illustrative purposes. Always consult official IRS resources or a tax professional for accurate tax planning.
Single Filers
| Tax Rate | Taxable Income |
|---|
Married Filing Jointly
| Tax Rate | Taxable Income |
|---|
Head of Household
| Tax Rate | Taxable Income |
|---|
Long-Term Capital Gains / Qualified Dividends Breakdown:
`; if (capitalGainsTaxDetails.length > 0) { capitalGainsTaxDetails.forEach(detail => { bracketBreakdownHtml += `Taxed \$${detail.amount.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })} at ${(detail.rate * 100).toFixed(0)}% (${detail.bracketRange}) = \$${detail.tax.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
`; }); } else { bracketBreakdownHtml += `No long-term capital gains/qualified dividends taxed or all fell into 0% bracket.
`; } } displayElements.bracketBreakdown.innerHTML = bracketBreakdownHtml; showTab('results'); // Switch to results tab after calculation } // --- PDF Download Functionality --- controlButtons.downloadPdf.addEventListener('click', function() { try { const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const margin = 20; let yPos = margin; // Title doc.setFont("helvetica", "bold"); doc.setFontSize(20); doc.setTextColor(37, 99, 235); /* Blue */ doc.text('Tax Bracket Analysis Report for Investors', doc.internal.pageSize.width / 2, yPos, { align: 'center' }); yPos += 15; // Tax Year and Disclaimer doc.setFont("helvetica", "normal"); doc.setFontSize(10); doc.setTextColor(107, 114, 128); /* Gray */ doc.text('Analysis for 2025 Tax Year (Estimated Brackets)', doc.internal.pageSize.width / 2, yPos, { align: 'center' }); yPos += 7; doc.text('Disclaimer: This report is an estimation for illustrative purposes only and should not be considered tax advice.', doc.internal.pageSize.width / 2, yPos, { align: 'center' }); yPos += 15; // Input Parameters doc.setFont("helvetica", "bold"); doc.setFontSize(14); doc.setTextColor(75, 85, 99); /* Dark Gray */ doc.text('Input Parameters', margin, yPos); yPos += 8; const inputData = [ ["Gross Income", `$${parseFloat(inputElements.grossIncome.value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`], ["Filing Status", inputElements.filingStatus.options[inputElements.filingStatus.selectedIndex].text], ["Long-Term Capital Gains", `$${parseFloat(inputElements.longTermCapitalGains.value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`], ["Qualified Dividends", `$${parseFloat(inputElements.qualifiedDividends.value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`], ["Other Deductions", `$${parseFloat(inputElements.otherDeductions.value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`] ]; doc.autoTable({ startY: yPos, head: [['Parameter', 'Value']], body: inputData, theme: 'grid', styles: { fontSize: 10, cellPadding: 3, textColor: '#333', lineColor: '#eee', lineWidth: 0.1 }, headStyles: { fillColor: '#eef2ff', textColor: '#374151', fontStyle: 'bold' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 15; // Calculation Results doc.setFont("helvetica", "bold"); doc.setFontSize(14); doc.setTextColor(75, 85, 99); doc.text('Calculation Results', margin, yPos); yPos += 8; const resultsData = [ ["Gross Income", displayElements.displayGrossIncome.textContent], ["Total Deductions", displayElements.displayTotalDeductions.textContent], ["Taxable Income", displayElements.displayTaxableIncome.textContent], ["Total Tax Liability", displayElements.displayTaxLiability.textContent], ["Marginal Tax Rate", displayElements.displayMarginalRate.textContent], ["Effective Tax Rate", displayElements.displayEffectiveRate.textContent] ]; doc.autoTable({ startY: yPos, head: [['Metric', 'Value']], body: resultsData, theme: 'grid', styles: { fontSize: 10, cellPadding: 3, textColor: '#333', lineColor: '#eee', lineWidth: 0.1 }, headStyles: { fillColor: '#eef2ff', textColor: '#374151', fontStyle: 'bold' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 15; // Income Breakdown by Tax Bracket doc.setFont("helvetica", "bold"); doc.setFontSize(14); doc.setTextColor(75, 85, 99); doc.text('Income Breakdown by Tax Bracket', margin, yPos); yPos += 8; // Capture the bracket breakdown HTML content const bracketBreakdownHtml = displayElements.bracketBreakdown.innerHTML; // For autoTable, we need structured data, so parse the breakdown. // This is a simplified parsing. For complex dynamic content, consider html2canvas or more robust PDF generation. const breakdownLines = bracketBreakdownHtml.split('').filter(line => line.trim() !== '').map(line => { const text = line.replace(/<[^>]*>/g, '').trim(); // Remove HTML tags return [text]; }); doc.autoTable({ startY: yPos, body: breakdownLines, theme: 'plain', // Use plain theme for breakdown text styles: { fontSize: 9, cellPadding: 2, textColor: '#333' }, columnStyles: { 0: { cellWidth: 'wrap' } }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 15; // Add Tax Brackets Table doc.addPage(); // Start new page for brackets if content is long yPos = margin; // Reset Y position for new page doc.setFont("helvetica", "bold"); doc.setFontSize(16); doc.setTextColor(37, 99, 235); doc.text('2025 Federal Income Tax Brackets (Estimated)', doc.internal.pageSize.width / 2, yPos, { align: 'center' }); yPos += 15; // Single Filers Table doc.setFont("helvetica", "bold"); doc.setFontSize(12); doc.setTextColor(75, 85, 99); doc.text('Single Filers', margin, yPos); yPos += 8; const singleBracketData = taxBrackets["single"].map(b => [ `${(b.rate * 100).toFixed(0)}%`, b.max === Infinity ? `\$${b.min.toLocaleString()} or more` : `\$${b.min.toLocaleString()} to \$${b.max.toLocaleString()}` ]); doc.autoTable({ startY: yPos, head: [['Tax Rate', 'Taxable Income']], body: singleBracketData, theme: 'grid', styles: { fontSize: 9, cellPadding: 2, textColor: '#333', lineColor: '#eee', lineWidth: 0.1 }, headStyles: { fillColor: '#eef2ff', textColor: '#374151', fontStyle: 'bold' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 10; // Married Filing Jointly Table doc.setFont("helvetica", "bold"); doc.setFontSize(12); doc.setTextColor(75, 85, 99); doc.text('Married Filing Jointly', margin, yPos); yPos += 8; const marriedJointlyBracketData = taxBrackets["marriedJointly"].map(b => [ `${(b.rate * 100).toFixed(0)}%`, b.max === Infinity ? `\$${b.min.toLocaleString()} or more` : `\$${b.min.toLocaleString()} to \$${b.max.toLocaleString()}` ]); doc.autoTable({ startY: yPos, head: [['Tax Rate', 'Taxable Income']], body: marriedJointlyBracketData, theme: 'grid', styles: { fontSize: 9, cellPadding: 2, textColor: '#333', lineColor: '#eee', lineWidth: 0.1 }, headStyles: { fillColor: '#eef2ff', textColor: '#374151', fontStyle: 'bold' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 10; // Head of Household Table doc.setFont("helvetica", "bold"); doc.setFontSize(12); doc.setTextColor(75, 85, 99); doc.text('Head of Household', margin, yPos); yPos += 8; const headOfHouseholdBracketData = taxBrackets["headOfHousehold"].map(b => [ `${(b.rate * 100).toFixed(0)}%`, b.max === Infinity ? `\$${b.min.toLocaleString()} or more` : `\$${b.min.toLocaleString()} to \$${b.max.toLocaleString()}` ]); doc.autoTable({ startY: yPos, head: [['Tax Rate', 'Taxable Income']], body: headOfHouseholdBracketData, theme: 'grid', styles: { fontSize: 9, cellPadding: 2, textColor: '#333', lineColor: '#eee', lineWidth: 0.1 }, headStyles: { fillColor: '#eef2ff', textColor: '#374151', fontStyle: 'bold' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 10; doc.save('Tax_Bracket_Analysis_Report.pdf'); } catch (error) { console.error("Error generating PDF:", error); // In a real application, you'd show a user-friendly modal here instead of just logging. // For example: // const errorModal = document.createElement('div'); // errorModal.textContent = "Failed to generate PDF. Please try again or check console for details."; // errorModal.style.cssText = "position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:red;color:white;padding:15px;border-radius:8px;z-index:9999;"; // document.body.appendChild(errorModal); // setTimeout(() => document.body.removeChild(errorModal), 5000); } }); // Initial population of tax bracket tables populateTaxBracketTables(); // Initial tab display showTab('inputs'); });