No feeds yet. Add your first feed to get started.
History
{% else %}
{% endif %}
{% if not posts and not selected_home and not is_chunk_delta_fetch %}
{% endif %}
{% for post in posts %}
{% set list_feed_query = '&list_feed_url=' ~ (selected_feed_url | urlencode) if selected_feed_url else '' %}
{% set tag_query = '&tag=' ~ (selected_tag | urlencode) if selected_tag else '' %}
{# Only include sort/filter params when non-default to keep URLs clean #}
{# Post links stay on the node they were clicked from, so in the Inbox
they must carry `kept=starred` too — the star order is only honored
there, and without it opening an article would silently re-sort the
list behind it. #}
{% set sort_query = ('&kept=starred' if inbox_view else '') ~ (('&sort_by=' ~ selected_sort_by) if selected_sort_by != 'post' else '') ~ (('&sort_dir=' ~ selected_sort_dir) if selected_sort_dir != 'asc' else '') %}
{% set read_filter_query = (('&read_filter=' ~ selected_read_filter) if selected_read_filter != 'all' else '') ~ ('&star_only=1' if selected_star_only else '') ~ (('&resume_read_filter=' ~ selected_resume_read_filter) if selected_resume_read_filter != selected_read_filter else '') %}
{% set _is_data_thumb = post.thumbnail_url and post.thumbnail_url.startswith('data:') %}
{% if post.is_locked %}
{# A supporter-locked webcomic strip (hide_locked_comics off, so the row
still shows): the resolved thumbnail is stale/unresolvable while
locked, so show the unlock date instead of a broken image. #}
{% endfor %}
{{ post.locked_until_display }}
{% else %}
{% if _is_data_thumb %}
{# Inline-SVG thumbnail: render the sanitized data URI directly (CSS sizes it; /thumb only rasterizes http(s)). #}
{% elif post.thumbnail_url %}
{# data-direct: if /thumb fails (e.g. the image host IP-blocks our server
but serves the browser's own IP fine), fall back to the direct URL so
the thumbnail still loads. CSS object-fit:cover sizes the un-resized image. #}
{# lazy: rows hidden by chunking or "Filter this view" are display:none and never intersect, so their thumbnails are not fetched (and resized server-side) until shown. #}
{% endif %}
{% endif %}
{# Always render both timestamps as data attributes and let JS pick which to display #}