{% if summary %}
read {{ summary.generated_at.strftime("%H:%M UTC") }}

{{ summary.content | glossary(tone) }}

{% else %}
read summary pending — generated hourly @ :07 UTC
{% endif %} {% if not quotes %}
no data yet — scheduler may not have run
{% else %} {% if has_anchor %}{% endif %} {% for q in quotes %} {% set is_stale = stale_symbols and q.symbol in stale_symbols %} {# Stale rows (last observation older than the group's freshness threshold) are hidden from the default UI but the server still computes them — remove the `{% if not is_stale %}` guard to resurface the dimmed row + stale tag. #} {% if not is_stale %} {% set tip = notes.get(q.symbol, '') if notes else '' %} {# Long Eurostat ('dataset?...') and ONS ('topic/.../cdid/dataset') symbols get truncated for display; hover shows the full identifier via title. Other symbols pass through. #} {% set short_sym = q.symbol %} {% if '?' in short_sym %}{% set short_sym = short_sym.split('?')[0] %}{% endif %} {% if '/' in short_sym %}{% set short_sym = short_sym.split('/')[-2] | upper %}{% endif %} {% for k in ["1d","1m","1y"] %} {% set v = q.changes.get(k) if q.changes else None %} {% endfor %} {% if has_anchor %} {% set va = q.changes.get('anchor') if q.changes else None %} {% endif %} {% endif %} {% endfor %}
SymbolLabel PriceCcy 1d1m1yanchoras-of
{{ short_sym }} {{ q.label or "" }} {{ q.price | price }} {{ q.currency or "" }} {% if v is none %}—{% else %}{{ "%+.2f"|format(v) }}%{% endif %} {% if va is none %}—{% else %}{{ "%+.2f"|format(va) }}%{% endif %} {{ q.as_of or "" }}
{% endif %}