Banner reuses image-text-banner (full-bleed) markup per v7. Skipped entirely when there's no banner image.
{data -> f:render.text(field: 'subheader')}
{data -> f:render.text(field: 'header')}
Category tab bar — populated client-side by timeline-tabs.js from each entry's
data-category below. Left empty/hidden here; the script only builds tabs (and
only shows this bar) when 2+ distinct categories are actually present, so a
Timeline with no categories filled in renders exactly as before.
Entries reuse image-and-content markup, alternating --reversed per v7.