{# TIMELINE (#331) — dated milestones on a vertical rule. Each event is a layout table of its own, so on paper `break-inside: avoid` keeps one whole, and the tables stack with no gap between them. No cell spans rows or columns: a browser shares a spanning cell's height among every row it spans, which stretched a fixed marker, and the lint refuses a merged body cell. The first row is the date, the marker and the title; the second the rule and the body. The marker is a capsule as tall as the title's line, drawn as two half-cells each bordered on three sides, so it meets the rule above and below it with no gap. The rule is the left border of the right half of the marker's column, which is the border's width the wider, so the rule runs through the capsule's centre. Nothing runs above the first marker or below the last, whose rule cell is the border's width wider so its copy keeps the others' edge. A done event's marker is filled in the accent, the next one is a ring in the accent on its tint, and one still to come is a ring in the rule's tone. A browser rounds the capsule; WeasyPrint and the Word engine draw a rectangle, which reads as the same marker. Context: subtitle — Optional italic standfirst events — List of dicts: date, title, body, state, last #} {% set rule = size.component.timeline_rule %} {% set half = ((size.component.timeline_marker - rule) / 2) | round(0, "floor") | int %} {% set line = (size.type.body * size.type.body_line) | round | int %} {% set pad = size.component.table_cell_pad %} {% if subtitle %}

{{ subtitle | escape_html }}

{% endif %} {% for event in events %} {% set ink = theme.palette.accent if event.state else theme.palette.rule_dark %} {% set fill = theme.palette.accent if event.state == "done" else (0.2 | heat_color(theme.palette.surface, theme.palette.accent) if event.state == "next" else theme.palette.surface) %} {% if event.last %} {% else %} {% endif %} {% if event.body %} {% else %} {% endif %} {% endfor %}