{#
feed.html
=========
Activity feed widget renderer.
Expects payload: { items: [{actor, verb, object, object_link?, at}] }
#}
{% macro feed_widget(title, payload) %}
<div class="feed-widget h-full flex flex-col p-md">
<div class="flex items-center justify-between gap-sm mb-sm flex-shrink-0">
<p class="text-label-sm text-outline uppercase tracking-wider truncate">{{ title }}</p>
{% if payload.view_all_url %}
<a
href="{{ payload.view_all_url }}"
class="text-label-sm text-on-surface-variant hover:text-primary transition-colors inline-flex items-center gap-1 flex-shrink-0 no-underline"
>
View all
<i data-lucide="arrow-up-right" class="w-3.5 h-3.5"></i>
</a>
{% endif %}
</div>
{% if payload.items and payload.items | length > 0 %}
{# Divider on each feed item — `surface-container-highest` gives
a barely-there separator in dark mode without the bluish-white
bloom `outline-variant` was leaving. Same token as the
scrollbar thumb so the two visual rails read as one family. #}
<ul class="flex-1 overflow-y-auto divide-y divide-surface-container-highest">
{% for item in payload.items %}
<li class="flex items-start gap-sm py-sm first:pt-0 last:pb-0">
<div class="w-7 h-7 rounded-full bg-surface-container-high border border-outline-variant/60 flex items-center justify-center flex-shrink-0 mt-0.5">
<span class="text-[10px] font-semibold text-on-surface-variant uppercase tracking-wide">{{ item.actor[:2] }}</span>
</div>
<div class="flex-1 min-w-0">
{# Username takes `on-surface-variant` (softer) instead of
`on-surface` (near-white) — pure white feels shouty in
dark mode and crowds the more important data (the verb
+ relative time). Hover bumps it to full contrast. #}
<p class="text-body-sm leading-snug">
<span class="font-medium text-on-surface-variant hover:text-on-surface transition-colors">{{ item.actor }}</span>
<span class="text-outline"> {{ item.verb }} </span>
{% if item.object_link %}
<a href="{{ item.object_link }}" class="text-primary hover:underline">{{ item.object }}</a>
{% else %}
<span class="text-on-surface-variant">{{ item.object }}</span>
{% endif %}
</p>
{# Relative time: "2 hours ago" reads at a glance; absolute
datetime lives in the tooltip for the rare "but exactly
WHEN?" question. #}
<time
class="text-label-sm text-outline/70 tabular-nums"
title="{{ item.at | humanize_date }}"
>{{ item.at | naturaltime }}</time>
</div>
</li>
{% endfor %}
</ul>
{% else %}
<p class="text-label-sm text-outline italic mt-auto">No recent activity.</p>
{% endif %}
</div>
{% endmacro %}