Barista Fire Calculator
.barista-fire-calculator {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 600px;
margin: 20px auto;
padding: 25px;
border: 1px solid #e0e0e0;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.barista-fire-calculator h2 {
color: #2c3e50;
text-align: center;
margin-bottom: 20px;
font-size: 1.8em;
}
.barista-fire-calculator p {
color: #34495e;
line-height: 1.6;
}
.calculator-input-group {
margin-bottom: 15px;
}
.calculator-input-group label {
display: block;
margin-bottom: 7px;
font-weight: bold;
color: #34495e;
}
.calculator-input-group input[type="number"] {
width: calc(100% – 20px);
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 1em;
box-sizing: border-box;
}
.barista-fire-calculator button {
display: block;
width: 100%;
padding: 12px 20px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
font-size: 1.1em;
cursor: pointer;
transition: background-color 0.3s ease;
margin-top: 20px;
}
.barista-fire-calculator button:hover {
background-color: #218838;
}
.calculator-results {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #eee;
}
.calculator-results h3 {
color: #2c3e50;
margin-bottom: 15px;
font-size: 1.5em;
}
.calculator-results p {
background-color: #eaf7ed;
padding: 10px 15px;
border-left: 4px solid #28a745;
margin-bottom: 10px;
color: #218838;
font-size: 1.05em;
}
.calculator-results p span {
font-weight: bold;
color: #000;
}
function calculateBaristaFIRE() {
// Get input values
var currentSavings = parseFloat(document.getElementById("currentSavings").value);
var essentialAnnualExpenses = parseFloat(document.getElementById("essentialAnnualExpenses").value);
var discretionaryAnnualExpenses = parseFloat(document.getElementById("discretionaryAnnualExpenses").value);
var expectedAnnualReturn = parseFloat(document.getElementById("expectedAnnualReturn").value) / 100;
var partTimeAnnualIncome = parseFloat(document.getElementById("partTimeAnnualIncome").value);
var annualSavingsAmount = parseFloat(document.getElementById("annualSavingsAmount").value);
var safeWithdrawalRate = parseFloat(document.getElementById("safeWithdrawalRate").value) / 100;
// Input validation
if (isNaN(currentSavings) || currentSavings < 0 ||
isNaN(essentialAnnualExpenses) || essentialAnnualExpenses <= 0 ||
isNaN(discretionaryAnnualExpenses) || discretionaryAnnualExpenses < 0 ||
isNaN(expectedAnnualReturn) || expectedAnnualReturn < 0 ||
isNaN(partTimeAnnualIncome) || partTimeAnnualIncome < 0 ||
isNaN(annualSavingsAmount) || annualSavingsAmount < 0 ||
isNaN(safeWithdrawalRate) || safeWithdrawalRate = targetNestEgg) {
yearsToBaristaFIRE = 0; // Already reached or surpassed
} else if (annualSavingsAmount <= 0 && currentPortfolioValue < targetNestEgg) {
yearsToBaristaFIRE = "Never (no savings)"; // Cannot reach if not saving and not already there
} else {
while (currentPortfolioValue 200) { // Prevent infinite loop for unrealistic scenarios
yearsToBaristaFIRE = "More than 200";
break;
}
}
}
// Calculate income and expenses in Barista FIRE
var incomeFromInvestments = essentialAnnualExpenses; // By definition of target nest egg
var incomeFromPartTime = partTimeAnnualIncome;
var totalAnnualExpenses = essentialAnnualExpenses + discretionaryAnnualExpenses;
var totalAnnualIncome = incomeFromInvestments + incomeFromPartTime;
var discretionaryCovered = Math.min(discretionaryAnnualExpenses, partTimeAnnualIncome);
var discretionaryUncovered = Math.max(0, discretionaryAnnualExpenses – partTimeAnnualIncome);
// Format currency
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 0
});
// Display results
document.getElementById("targetNestEgg").innerText = formatter.format(targetNestEgg);
document.getElementById("yearsToBaristaFIRE").innerText = (typeof yearsToBaristaFIRE === 'number') ? Math.round(yearsToBaristaFIRE) + " years" : yearsToBaristaFIRE;
document.getElementById("incomeFromInvestments").innerText = formatter.format(incomeFromInvestments);
document.getElementById("incomeFromPartTime").innerText = formatter.format(incomeFromPartTime);
document.getElementById("totalAnnualExpenses").innerText = formatter.format(totalAnnualExpenses);
document.getElementById("totalAnnualIncome").innerText = formatter.format(totalAnnualIncome);
document.getElementById("discretionaryCovered").innerText = formatter.format(discretionaryCovered);
document.getElementById("discretionaryUncovered").innerText = formatter.format(discretionaryUncovered);
}
// Run calculation on page load with default values
window.onload = calculateBaristaFIRE;