The Ledger
Projection
{% include 'includes/ledger_nav.html' %}
{% with messages = get_flashed_messages(with_categories=true) %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endwith %} {# Baseline summary header #}

Avalanche + snowball projection

Debt-free: {{ projection.debt_free_date or '—' }}
Months simulated {{ projection.monthly_rows | length }} Total interest paid ${{ '{:,.2f}'.format(projection.total_interest_paid) }}

Interest is accrued on remaining balances each month. Kills cascade allocation onto the next-highest-APR target.

{# Comparison strip — initially hidden, shown by JS when sandbox is active #} {# Tables — baseline always renders server-side; sandbox table is JS-rendered #}
// Month by month
{% if projection.monthly_rows %}
{% for r in projection.monthly_rows %} {% endfor %}
MonthStart Min Attack Interest EndTargetKill
{{ r.month }} ${{ '{:,.0f}'.format(r.starting_total) }} ${{ '{:,.0f}'.format(r.minimums_applied) }} ${{ '{:,.0f}'.format(r.attack_applied) }} ${{ '{:,.0f}'.format(r.interest_accrued) }} ${{ '{:,.0f}'.format(r.ending_total) }} {{ r.current_target_name or '—' }} {% if r.kill_account_name %}{{ r.kill_account_name }} ✓{% endif %}
{% else %}
No projection — no active debts to simulate.
{% endif %}
{# Sandbox table — JS populates and shows when active #}
{# ============= // SANDBOX panel ============= #}
// Sandbox — explore what-if scenarios without changing config
{# Control 1: Redirect bonuses #}
Redirect bonuses to debt
{% if bonus_count == 0 %}

No bonus income configured. Add bonuses on the Income page to enable this control.

{% elif next_bonus %}

Your next bonus lands {{ next_bonus.projected_next_date or next_bonus.event_date }}, ${{ '{:,.0f}'.format(next_bonus.amount) }} — toggle on to see the impact.

{% else %}

No future bonuses found. Add or update bonuses on the Income page.

{% endif %}
{# Control 2: Extra monthly attack #}

{# Control 3: Side income ramp #}
starts months from now
{# Control 4: Windfalls #}
{# JS appends rows here #}
{# Control 5: FedLoan override #}
starting in months

FedLoan currently configured at ${{ '{:.2f}'.format(current_fedloan_min or 0) }}/mo. Sandbox a different number to see the impact when forbearance ends.

{# ============= MILESTONE TIMELINE ============= #} {# ============= Apply modal ============= #}
{# Server-rendered current-target context for the apply modal #} {% include 'includes/today_panel.html' ignore missing %} {% include 'includes/active_timer_strip.html' ignore missing %}