The Ledger
Leak Hunt · {{ imp.period_start }} → {{ imp.period_end }}
{% include 'includes/ledger_nav.html' %}
{% with messages = get_flashed_messages(with_categories=true) %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endwith %} {# ===== Headline numbers ===== #}

Total outflow

${{ '{:,.2f}'.format(total_outflow) }}
Inflow ${{ '{:,.2f}'.format(total_inflow) }} Net ${{ '{:,.2f}'.format(total_outflow - total_inflow) }}

Period

{{ imp.period_start }} → {{ imp.period_end }}
Transactions {{ imp.transaction_count or 0 }} Source {{ imp.csv_filename or imp.source or '—' }}
← Back to review
{# ===== Comparison to prior hunt ===== #} {% if prior %}

vs. most recent prior hunt ({{ prior.period_start }} → {{ prior.period_end }})

{% set delta_total = total_outflow - (prior.total_amount or 0) %}
Δ {% if delta_total < 0 %}−${{ '{:,.2f}'.format(-delta_total) }} {% elif delta_total > 0 %}+${{ '{:,.2f}'.format(delta_total) }} {% else %}$0 {% endif %} in total spending
{% if delta_rows %} {% for d in delta_rows[:10] %} {% endfor %}
Category This hunt Prior Δ
{{ d.category }} ${{ '{:,.2f}'.format(d.now) }} ${{ '{:,.2f}'.format(d.prior) }} {% if d.delta < 0 %}−${{ '{:,.2f}'.format(-d.delta) }} {% elif d.delta > 0 %}+${{ '{:,.2f}'.format(d.delta) }} {% else %}—{% endif %}
{% endif %}
{% endif %} {# ===== Category breakdown ===== #}
// Category breakdown
{# Stacked bar — segments of brass at varying tints (opacity by rank). #} {% set spend_cats = breakdown | rejectattr('is_excluded') | list %} {% if total_outflow > 0 and spend_cats %}
{% for r in spend_cats %} {% if r.total > 0 %} {% set pct = (r.total / total_outflow * 100) %} {% set tint = [0.95, 0.78, 0.62, 0.50, 0.40, 0.32, 0.26, 0.22, 0.18, 0.15][loop.index0] if loop.index0 < 10 else 0.12 %}
{% if pct > 8 %}{{ r.category }}{% endif %}
{% endif %} {% endfor %}
{% for r in spend_cats %} {% if r.total > 0 %} {% set tint = [0.95, 0.78, 0.62, 0.50, 0.40, 0.32, 0.26, 0.22, 0.18, 0.15][loop.index0] if loop.index0 < 10 else 0.12 %} {{ r.category }} ${{ '{:,.0f}'.format(r.total) }} {% endif %} {% endfor %}
{% endif %}
{% for r in breakdown %} {% endfor %}
Category Total % outflow # Avg
{{ r.category }}{% if r.is_excluded %} (excluded from leak){% endif %} ${{ '{:,.2f}'.format(r.total) }} {% if r.is_excluded %}—{% else %}{{ '{:.1f}'.format(r.percent_of_outflow) }}%{% endif %} {{ r.count }} ${{ '{:,.2f}'.format(r.avg) }}
{# ===== Recurring callout ===== #} {% if recurring %}
// Recurring charges detected

Highest-leverage section — each one canceled is monthly savings forever. Use + Add to bills to drop a charge into Recurring expenses so the cash-runway card stops missing it. Add now → cancel later if you decide to.

{% for r in recurring %} {% endfor %}
Merchant Avg / charge Total in period Count
{{ r.description }}
{{ r.cleaned_name }}
${{ '{:,.2f}'.format(r.avg_amount) }} ${{ '{:,.2f}'.format(r.total) }} {{ r.count }}
{% set recurring_total = recurring | sum(attribute='avg_amount') %} {% if recurring_total > 50 %}

Recurring charges total ~${{ '{:,.0f}'.format(recurring_total) }}/mo (avg). Each one canceled is ${{ '{:,.0f}'.format(recurring_total) }} freed monthly toward debt.

{% endif %}
{% endif %} {# ===== Biggest surprises ===== #} {% if biggest %}
// Biggest individual transactions
{% for t in biggest %} {% endfor %}
DateDescriptionCategory Amount
{{ t.tx_date }} {{ t.description }} {{ t.category }} ${{ '{:,.2f}'.format(t.amount) }}
{% endif %} {# ===== Notes ===== #}
// What did you learn?
← All hunts Re-categorize
{% include 'includes/today_panel.html' ignore missing %} {% include 'includes/active_timer_strip.html' ignore missing %}