{% extends 'base.html' %} {% load static %} {% comment %} Renewal Calendar — Phase 9. Forward-looking month-by-month grid of contract renewals, grouped by currency. Cells show the total contract value renewing in that month; saturation encodes magnitude (relative to the visible window's max); clicking a cell drills into the contract list filtered to that month. Why a rather than a CSS-Grid div: Screen readers handle
++
idiomatically — row/column navigation, header announcements, scope. Replicating that with ARIA on grid divs is achievable but fragile. The visual layout uses CSS Grid via display: grid on the table, which preserves both the accessibility tree and the modern layout. Color choice: Amber (hsl 35) at 50% lightness saturated, 95% pale. "Renewals cost attention" matches amber's UI semantics (warning, not danger). No purple per the operator's standing rule. Context (from views/calendar.py): grid — list of {year, month, label, totals, contract_count, saturation} currencies — sorted set of currency codes present in the window months — window length (1–36) today — date.today() for highlighting the current month column {% endcomment %} {% block title %}Renewal Calendar{% endblock %} {% block extra_styles %} {% endblock %} {% block content %}

Renewal Calendar

Total contract value renewing each month over the next {{ months }} month{{ months|pluralize }}. Cells link through to the contract list filtered to that month.

{% if currencies %}
{% for cell in months_grid %} {% endfor %} {% for row in rows %} {% for cell in row.cells %} {% if cell.total %} {% else %} {% endif %} {% endfor %} {% endfor %}
Currency {{ cell.label }} {{ cell.year }}
{{ row.currency }} {{ cell.total|floatformat:0 }} {{ cell.contract_count }}
Spend intensity: 0 relative max Each cell shows total contract value (recurring × term + one-time fees) and the count of contracts renewing.
{% else %}

No renewals in the next {{ months }} month{{ months|pluralize }}.

This is a fleet-wide forward view; if you expected renewals here, check that contracts have an end_date set.

{% endif %}
{% endblock %}