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.

{entry -> f:render.text(field: 'eyebrow')}

{entry -> f:render.text(field: 'title')}

{entry -> f:render.text(field: 'bodytext')}
{entry.link.title -> f:format.trim()} {customCtaLabel} {entry.title}: {readMoreLabel} {readMoreLabel}