{# Reusable fragments. `ticker_card` renders one symbol tile; its data-ticker and data-field hooks let the live stream client patch it in place. #} {# `verdict_badge` renders the rolled-up strong / fair / weak standing badge (Phase 20). `s` is a compute::Standing: `s.grade` is the colour hook (good/ok/bad), `s.verdict` the word (Strong/Fair/Weak). #} {% macro verdict_badge(s) %}{{ s.verdict }}{% endmacro %} {% macro ticker_card(c) %}
{{ c.ticker }} {% if c.strength %}{{ verdict_badge(c.strength) }}{% endif %} {{ c.kind }}
{{ c.name }}
{{ c.price|money }} {{ c.change_pct|pct }}
{% endmacro %} {# `spark_card` renders one dashboard tile: an intraday sparkline with a live price and day change. data-lo/data-hi let the stream client place a live quote on the same y-scale and nudge the trailing point. #} {% macro spark_card(c) %}
{{ c.ticker }} {{ c.name }}
{% if c.spark %} {% else %}
no intraday data
{% endif %}
{{ c.price|money }} {{ c.change_pct|pct }}
{% endmacro %} {# `etf_card` renders one curated ETF tile (Phase 5): the same intraday sparkline + live price as `spark_card`, plus the Phase-4 quality verdict as a small pill in the head so the fund's quality reads at a glance beside its move. `e.card` is a SparkCard; `e.quality` an EtfQuality (None until ≥2 factors grade). #} {% macro etf_card(e) %}
{{ e.card.ticker }} {{ e.card.name }} {% if e.quality %}{{ e.quality.verdict }}{% endif %}
{% if e.card.spark %} {% else %}
no intraday data
{% endif %}
{{ e.card.price|money }} {{ e.card.change_pct|pct }}
{% endmacro %} {# `etf_pill` renders one compact ETF mover (Phase 5): ticker + day move, with a small quality dot tinting the pill by the fund's overall grade. #} {% macro etf_pill(m) %} {% if m.quality %}{% endif %} {{ m.ticker }} {{ m.change_pct|pct }} {% endmacro %} {# `mover_row` renders one gainer/loser row. The `--bar` custom property sizes a soft magnitude tint behind the row, scaled by the route. The badge cell is always present (empty for a stock without a synced standing) so the row's grid keeps a fixed column count. #} {% macro mover_row(m) %} {{ m.ticker }} {{ m.name }} {% if m.strength %}{{ verdict_badge(m.strength) }}{% endif %} {{ m.price|money }} {{ m.change_pct|pct }} {% endmacro %} {# `health_row` renders one quality-leaderboard row (Phase 17, reframed in Phase 3). The overall verdict badge sits on the right; the three sub-readings ride below the name as a compact line so the synthesis is legible without expanding, and the trailing-year return sits between as a quiet price anchor. `--bar` sizes the magnitude tint, scaled by the route to the largest score shown. #} {% macro health_row(r) %} {{ r.ticker }} {{ r.name }} {{ r.health.strength_label }} {{ r.health.trajectory_label }} {{ r.health.stability_label }} {% if r.ret_12m is not none %}{{ r.ret_12m|pct }}{% endif %} {{ verdict_badge({"grade": r.health.overall, "verdict": r.health.verdict}) }} {% endmacro %}