Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/features/AccumulationStrategy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const AccumulationStrategy: React.FC<AccumulationStrategyProps> = ({ profile, se
<div className="flex items-center gap-1 bg-slate-100 dark:bg-slate-800 p-1 rounded-lg border border-slate-200 dark:border-slate-700">
<button onClick={() => setIsInflationAdjusted(false)} className={`px-4 py-2 text-xs font-bold rounded-md min-h-[36px] transition-colors ${!isInflationAdjusted ? 'bg-white dark:bg-slate-700 text-blue-600 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}>Nominal</button>
<button onClick={() => setIsInflationAdjusted(true)} className={`px-4 py-2 text-xs font-bold rounded-md min-h-[36px] transition-colors ${isInflationAdjusted ? 'bg-white dark:bg-slate-700 text-blue-600 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}>Adj Inflation's $</button>
<Tooltip content="Shows future portfolio balances adjusted for inflation (Today's Purchasing Power) versus unadjusted Nominal values." className="mr-1" />
<Tooltip content="Clarifies the difference between the 'face value' of the portfolio in the future vs. its equivalent value in today's economy." className="mr-1" />
</div>
</div>
<div className="flex flex-col sm:flex-row gap-6 items-center">
Expand Down
6 changes: 3 additions & 3 deletions src/components/features/FireAnalysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,11 @@ const FireAnalysis: React.FC<FireAnalysisProps> = ({ profile, isDarkMode }) => {
<div className="flex items-center justify-between mb-1">
<h4 className="text-lg font-bold text-slate-900 dark:text-white flex items-center gap-2">
{milestone.type} FIRE
{milestone.type === 'Lean' && <Tooltip content="Goal: Minimalist living expenses covered." className="ml-1" />}
{milestone.type === 'Lean' && <Tooltip content="You have enough to cover basic living expenses, but with little room for luxury." className="ml-1" />}
{milestone.type === 'Standard' && <Tooltip content="Goal: Current lifestyle technically 'independent'." className="ml-1" />}
{milestone.type === 'Fat' && <Tooltip content="Goal: Luxury lifestyle with buffer." className="ml-1" />}
{milestone.type === 'Coast' && <Tooltip content="Goal: Saved enough to stop contributing today." className="ml-1" />}
{milestone.type === 'Barista' && <Tooltip content="Assumes you work part-time to earn supplemental income." className="ml-1" />}
{milestone.type === 'Coast' && <Tooltip content="You've saved enough that you no longer need to contribute to reach your goal, but still need to work to cover current expenses." className="ml-1" />}
{milestone.type === 'Barista' && <Tooltip content="Your portfolio covers a portion of your expenses, allowing you to switch to a lower-stress part-time job." className="ml-1" />}
{milestone.percentageProgress >= 100 && (
<span className="px-2 py-0.5 text-[10px] font-bold uppercase bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400 rounded-full">
Achieved
Expand Down
16 changes: 8 additions & 8 deletions src/components/features/InputSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ const InputSection: React.FC<InputSectionProps> = ({ profile, setProfile, onRest
// const resetToToday = () => { ... }

const inputClass = "w-full rounded-md border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 text-slate-900 dark:text-white shadow-sm focus:border-blue-500 focus:ring-blue-500 border p-2 transition-colors";
const labelClass = "block text-sm font-medium text-slate-600 dark:text-slate-300 mb-1";
const labelClass = "flex items-center gap-1 text-sm font-medium text-slate-600 dark:text-slate-300 mb-1";
const iconClass = "absolute left-3 top-2 text-slate-400 dark:text-slate-500";
const containerClass = "bg-white dark:bg-slate-900 rounded-xl shadow-sm border border-slate-200 dark:border-slate-800 p-6 space-y-8 transition-colors";
const headerClass = "text-xl font-bold text-slate-800 dark:text-white flex items-center gap-2 mb-4";
Expand Down Expand Up @@ -177,9 +177,9 @@ const InputSection: React.FC<InputSectionProps> = ({ profile, setProfile, onRest
</div>
<div className="md:col-span-2">
<div className="flex items-center justify-between mb-1">
<label htmlFor="spendingNeed" className="text-sm font-medium text-slate-600 dark:text-slate-300">
<label htmlFor="spendingNeed" className="text-sm font-medium text-slate-600 dark:text-slate-300 flex items-center gap-1">
Annual Spending Need
<Tooltip content="Estimated annual retirement living expenses (net of taxes). The strategy engine will calculate the gross withdrawal needed to cover this amount plus estimated federal taxes." className="ml-1" />
<Tooltip content="Annual Spending Need in Retirement. This is your target annual budget (net of taxes) once retired." />
</label>
<div className="flex bg-slate-100 dark:bg-slate-800 p-1 rounded-lg border border-slate-200 dark:border-slate-700 text-xs font-bold">
<button
Expand All @@ -190,9 +190,9 @@ const InputSection: React.FC<InputSectionProps> = ({ profile, setProfile, onRest
onClick={() => handleChange('isSpendingReal', false)}
className={`px-3 py-1.5 rounded-md min-h-[32px] transition-colors ${!profile.isSpendingReal ? 'bg-white dark:bg-slate-600 text-blue-600 dark:text-blue-300 shadow-sm' : 'text-slate-500 hover:text-slate-700'}`}
>Future $</button>
<Tooltip content="Select whether your spending goal is measured in today's purchasing power (adjusted for inflation) or future nominal dollars." className="ml-1 mt-1.5">
<div className="w-4 h-4" />
</Tooltip>
<div className="flex items-center pr-1 pl-1">
<Tooltip content="Today's $ represents values in current purchasing power. Future $ shows nominal amounts inflated at your target rate." />
</div>
</div>
</div>
<div className="relative">
Expand All @@ -219,9 +219,9 @@ const InputSection: React.FC<InputSectionProps> = ({ profile, setProfile, onRest
{[
{ label: 'Traditional IRA / 401k', key: 'traditionalIRA' as const },
{ label: 'Roth IRA / 401k', key: 'rothIRA' as const },
{ label: 'Roth Carry/Basis', key: 'rothBasis' as const, tooltip: 'Your total accumulated contributions to Roth accounts. This basis can be withdrawn tax-free and penalty-free at any time, making it a key liquidity source before age 59½.' },
{ label: 'Roth Carry/Basis', key: 'rothBasis' as const, tooltip: "The total amount of after-tax principal you've contributed to your Roth accounts. This portion can always be withdrawn tax-free and penalty-free." },
{ label: 'Taxable Brokerage', key: 'brokerage' as const },
{ label: 'HSA', key: 'hsa' as const, tooltip: 'Health Savings Account balance. Funds can be withdrawn tax-free for qualified medical expenses.' },
{ label: 'HSA', key: 'hsa' as const, tooltip: "Health Savings Account. A triple-tax-advantaged account where contributions are tax-deductible, growth is tax-free, and withdrawals for medical expenses are tax-free." },
].map((item) => (
<div key={item.key}>
<label htmlFor={`asset-${item.key}`} className={labelClass}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/features/LongevityAnalysis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const LongevityAnalysis: React.FC<LongevityAnalysisProps> = ({ longevity, profil
}`}>
<h3 className={`text-sm font-medium uppercase flex items-center gap-2 ${sustainable ? 'text-green-800 dark:text-green-400' : 'text-orange-800 dark:text-orange-400'}`}>
Initial Withdrawal Rate
<Tooltip content="The percentage of your total portfolio withdrawn in the first year of retirement to cover expenses and taxes. Lower is safer." />
<Tooltip content="The percentage of your portfolio you'll withdraw in the first year of retirement. 4% is traditionally considered a 'safe' benchmark." />
</h3>
<div className="flex items-baseline gap-2 mt-1">
<span className="text-3xl font-bold text-slate-900 dark:text-white">{(initialWithdrawalRate * 100).toFixed(1)}%</span>
Expand Down Expand Up @@ -286,7 +286,7 @@ const LongevityAnalysis: React.FC<LongevityAnalysisProps> = ({ longevity, profil
{/* RMD indicator (age 73+) */}
{data.rmdAmount > 0 && (
<div className="flex justify-between items-center text-orange-600 dark:text-orange-400 text-[10px] italic">
<span className="flex items-center gap-1">(RMD Required): <Tooltip content="Required Minimum Distribution: The minimum amount the IRS requires you to withdraw from tax-deferred accounts annually." /></span>
<span className="flex items-center gap-1">(RMD Required): <Tooltip content="Required Minimum Distribution. The mandatory annual withdrawal amount from tax-deferred accounts (like Traditional IRAs) starting at age 73 or 75." /></span>
<span className="font-mono">${Math.round(data.rmdAmount).toLocaleString()}</span>
</div>
)}
Expand Down
6 changes: 3 additions & 3 deletions src/components/features/StrategyResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ const StrategyResults: React.FC<StrategyResultsProps> = ({ result, profile, isDa
<p className="font-bold text-slate-900 dark:text-white">{formatCurrency(result.taxableSocialSecurity)}</p>
</div>
<div className="p-2 bg-slate-50 dark:bg-slate-800 rounded">
<span className="text-slate-500 flex items-center gap-1">Provisional Income <Tooltip content="IRS formula used to determine how much of your Social Security benefits are subject to federal income tax." /></span>
<span className="text-slate-500 flex items-center gap-1">Provisional Income <Tooltip content="An IRS formula (Social Security + 50% of benefits + other income) used to determine how much of your Social Security is taxable." /></span>
<p className="font-bold text-slate-900 dark:text-white">{formatCurrency(result.provisionalIncome)}</p>
</div>
<div className="p-2 bg-slate-50 dark:bg-slate-800 rounded">
Expand Down Expand Up @@ -249,7 +249,7 @@ const StrategyResults: React.FC<StrategyResultsProps> = ({ result, profile, isDa
</p>
</div>
<div className="p-2 bg-slate-50 dark:bg-slate-800 rounded">
<span className="text-slate-500 text-[10px] flex items-center gap-1">Effective Marginal Rate <Tooltip content="The actual tax rate paid on your last dollar of income, accounting for hidden taxes like the Social Security tax torpedo." /></span>
<span className="text-slate-500 text-[10px] flex items-center gap-1">Effective Marginal Rate <Tooltip content="The tax rate applied to your very last dollar of income, which can be higher than your average rate due to deduction phase-outs." /></span>
<p className={`font-bold ${result.rothConversionDetail.effectiveMarginalRate > 0.30
? 'text-red-600 dark:text-red-400'
: 'text-slate-900 dark:text-white'
Expand Down Expand Up @@ -311,7 +311,7 @@ const StrategyResults: React.FC<StrategyResultsProps> = ({ result, profile, isDa
<div className="text-right">
{c.headroom > 0 && <span className="text-slate-600 dark:text-slate-400">Headroom: {formatCurrency(c.headroom)}</span>}
{c.annualCost && c.annualCost > 0 && (
<p className="text-red-500 text-[10px] flex items-center gap-1 justify-end">IRMAA: {formatCurrency(c.annualCost)}/yr if crossed <Tooltip content="Income-Related Monthly Adjustment Amount: A surcharge added to your Medicare Part B and Part D premiums if your income is too high." /></p>
<p className="text-red-500 text-[10px] flex items-center gap-1 justify-end">IRMAA: {formatCurrency(c.annualCost)}/yr if crossed <Tooltip content="Income-Related Monthly Adjustment Amount. A surcharge added to Medicare premiums if your modified adjusted gross income (MAGI) exceeds certain cliffs." /></p>
)}
</div>
</div>
Expand Down