Add interactive timeline embed component

Add interactive timeline embed component

#58 in Riparion/riparion-cms — merged 2026-06-04

Summary

A new timeline embed renders a live, interactive timeline infographic: dated entries with icons, colours, and captions along a banded arrow (horizontal) or a stacked spine (vertical), with click/keyboard selection, an animated progress fill, a detail panel, and an in-component orientation toggle (a Switch in the upper-right). Horizontal is the responsive default on wide screens, vertical on narrow ones; the toggle forces either at any width.

How it works

A timeline holds a variable-length list of structured entries, which the flat [[/name key="value"]] grammar can't carry. So this adds a PropKind::EntryList(&[PropSpec]) variant whose value is stored as base64(JSON) in a single prop — quote/newline/space-free, so it round-trips the embed grammar and the inline-on-delete rewrite untouched (no migration, no new table; reuses the whole saved-component pipeline).

Timelines are authored as global components: the Components admin form gains a repeating-card entry editor (add / remove / reorder, each entry = date / title / description / icon / colour / placement), and bodies reference them by id ([[/timeline id=N]]). EntryList-bearing tags are "saved-only" (derived from the schema, not a hand-set flag) and hidden from the inline slash menu so authors never hit an empty inline placeholder.

Also included

  • /help/timeline help article + a row in the embeds smart-tags table.
  • Seed data: a "Company history" timeline component and an "Our journey" post (/post/our-journey) referencing it, so a fresh DB ships a real interactive example.

Verification

  • cargo fmt --all --check
  • clippy -D warnings on web (wasm32), server (sqlite), and server (postgres)
  • cargo test — 52 pass (timeline codec round-trip, grammar-safe encoding, malformed→empty, placement, saved-only derivation)
  • Throwaway DX_SEED=1 run confirms the component + post seed and the post body wires to the seeded id
  • Driven in a real browser (admin entry editor, public post, orientation toggle, vertical/horizontal parity)
  • Self-review (/code-review) findings addressed; /security-review found no issues

Note: assets/tailwind.css is gitignored and regenerated by CI (this PR adds new utilities like md:hidden/tl-spine); CI's Tailwind step picks them up.

🤖 Generated with Claude Code

Last updated 2026-06-04