{% elif sessions and sessions|length > 1 %}
{{ render_session_nav(sessions, "toc") }}
{% endif %}
{% macro render_message(message) %}
{%- set message_title = message.rendered_title %}
{%- set html_content = message.rendered_html %}
{%- set formatted_timestamp = message.rendered_timestamp %}
{% if message.fork_only %}
{# Fork-only landmark (#233 follow-up): this slot is a fork point whose own
message body was filtered out at the current detail level, but it is kept
(not ghosted) so the fork point stays visible and anchorable — like the
branches it connects. Render ONLY the fork-point box (no message card),
at the slot's original position. The anchor id lives on the box so branch
back-links (`from ⟂ Fork point`) and the nav fork item resolve here. #}
{% for child in message.children %}{{ render_message(child) }}{% endfor %}{% if message.junction_forward_links %}
{% elif is_session_header(message) %}
{% if not message.is_branch_header %}{% endif %}
{# Structural wrapper: the message card and its nested .children render as
SIBLINGS here, so the card's border/background/margins frame only the
card itself, not the whole subtree (issue #174 nested-DOM follow-up). #}
{% if message.is_branch_header %}↳ {% else %}Session: {% endif %}{{ html_content|safe }}{% if message.display_model and not message.is_branch_header %} {{ message.display_model }}{% endif %}
{% if message.has_children %}
{% if message.immediate_children_count == message.total_descendants_count %}
{# Same count = only one level, show single full-width button #}
⏷{{ message.get_immediate_children_label() }}
{% else %}
{# Multiple levels, show both buttons #}
⏷{{ message.get_immediate_children_label() }}
⏷⏷{{ message.get_total_descendants_label() }} total
{% endif %}
{% endif %}
{% if message.children or message.junction_forward_links %}
{% for child in message.children %}{{ render_message(child) }}{% endfor %}{% if message.junction_forward_links %}
{# Fork point — rendered INSIDE .children so it folds together with the
subtree (folding hides .children). For a childless junction it is the
sole occupant. The opening tag is glued to endfor so non-junction
nodes emit no extra whitespace. #}
{% elif message.should_render %}
{%- set msg_css_class = css_class_from_message(message) %}
{% set markdown = message.content.has_markdown if message.content else false %}
{# data-uuid: the message's transcript UUID — stable across re-renders,
unlike the positional msg-d-N slot ids (see work/archive-search-server.md,
"The anchor problem"). Archive search / annotations can deep-link on it.
NOT unique per card: sibling cards split from one entry (text + tool_use)
share the entry's UUID, so anything needing per-card identity within a
page must use the card's `id` (msg-…) or element identity instead. #}
{% set msg_emoji = get_message_emoji(message) -%}
{% if message_title %}{%
if message_title == 'Memory' %}💭 {%
elif msg_emoji and (message.type != 'tool_use' or not starts_with_emoji(message_title)) %}{{ msg_emoji }} {% endif %}{{ message_title | safe }}{% endif %}
{{ formatted_timestamp }}
{% if message.token_usage %}
{{ message.token_usage }}
{% endif %}
{% if message.immediate_children_count == message.total_descendants_count %}
{# Same count = only one level, show single full-width button #}
⏷{{ message.get_immediate_children_label() }}
{% else %}
{# Multiple levels, show both buttons #}
⏷{{ message.get_immediate_children_label() }}
⏷⏷{{ message.get_total_descendants_label() }} total
{% endif %}
{% endif %}
{% if message.children or message.junction_forward_links %}
{% for child in message.children %}{{ render_message(child) }}{% endfor %}{% if message.junction_forward_links %}
{# Fork point — rendered INSIDE .children so it folds together with the
subtree (folding hides .children). For a childless junction it is the
sole occupant. The opening tag is glued to endfor so non-junction
nodes emit no extra whitespace. #}