Six dated entries alternating across one continuous hairline down the centre of the section. Core blocks only: core/group, core/columns, core/column, core/heading, core/paragraph.
The signature moment
The rule is continuous and the reading is not
The signature is the crossing. One currentColor rule runs the whole height of the section down its exact centre and never breaks. The copy crosses it six times: 1904 hangs left of the line and is set right-aligned hard against it, 1931 hangs right and is set left-aligned out of it, and so on to 2023. The eye zig-zags down a mark that does not move, and that alternation is what makes six entries read as a history rather than as a list of six things. A single-sided rail reads as an index; a crossing reads as time passing.
The rule also runs past both ends. The first entry takes a spacing-80 top padding and the last a spacing-80 bottom padding, so the line exists for a stretch where there is nothing beside it at either end. A history that begins exactly at its first entry and stops exactly at its last one is a closed list. This one is a length cut out of something longer, and the lede says so.
How the rule is built, and why it is unbroken
There is no rail element and no separator block. Each entry is a core/columns of two 50% columns; the left column of every row carries a border-right of currentColor 1px, and consecutive rows carry no vertical block gap ("blockGap":{"top":"0px","left":"0px"} on the columns, "0px" on the section group), so those six borders touch and form one line. The horizontal gap is 0px as well, which is what puts the border at the exact centre rather than half a gutter off it. All the spacing between entries comes from each entry's own top and bottom padding, never from a gap between rows. This is the technique timeline-rail uses for its single-sided rail, applied to a two-sided one.
The half that only works here: an entry on the RIGHT puts its copy in the right column and leaves the left column completely empty, holding nothing but its border. A flex column stretches to the height of its row, so the empty column is as tall as the copy beside it and the rule carries on through rows it has no content in. That is why the border is on the column itself rather than on a group inside it, which is where timeline-rail puts it: a group sizes to its content, and an empty group is a gap in the line.
What happens at 390
The columns do not stack. isStackedOnMobile: false, because stacking would destroy the composition in a way no honest description could dress up: the empty column would collapse to zero height and the rule would vanish on every right-hand entry, leaving three orphaned lines down the right edge of the phone. So the crossing is kept at every width. At 390 that means two 179px halves with the rule between them and the copy alternating either side of it, which is tighter than a phone would ideally set it: roughly 22 characters to the line, against about 40 in a full-width section. It reads, it is still recognisably the same design, and the entries are written short for that reason. If your entry copy runs to three or four sentences, the phone rendering is where you will see it first. A four-digit year at the clamp() floor needs nothing like the width available, so the years are never the problem.
What it inherits from your theme
- The typeface. No font family is stated anywhere.
- Your colours.
basefor the ground,contrastfor the type, both ending on a colour WordPress itself guarantees. The centre rule iscurrentColor, so it follows your text colour, cannot resolve to nothing, and inverts with the section if you recolour it. - Your spacing scale. Every vertical gap, including the run-past at both ends of the rule, is a spacing preset, so a theme with a generous scale gets a longer overhang and more air between entries.
What it decides for itself
- Full bleed with a 1240px measure.
- The 50/50 split and the zero gutter, which together are what put the rule on the centre line rather than near it.
- The alternation, and the text alignment that goes with it: left-hand entries are right-aligned into the rule, right-hand entries are left-aligned out of it. Both sides are set against the line, never away from it.
- The measure, held by the column rather than by a nested constrained group: half of 1240 less the gutter runs at about 70 characters at the widest, which is inside the band body copy wants.
What to change first
- The six entries. To add one, duplicate a whole
core/columnsrow and put its copy in the OTHER column from the row above it, so the alternation keeps going. The empty column stays empty; do not delete it, because it is the piece carrying the rule. - Which end runs past. The first row carries the larger top padding and the last row the larger bottom padding. Those two values are the run-past, and they belong to whichever rows are first and last, not to 1904 and 2023.
- The years. Plain text, so
1904,Spring 1904orQ1all set. - The entry copy. One sentence that says what changed. Two still fit. Three turn a crossing into two columns of prose with a line between them, and it is the phone that shows it.
- The heading and lede. Written to say the line is open at both ends. If you close it by removing the run-past, change that sentence too.
- The finish. Ship the base where the section should feel like a document, and
crossing-plateswhere it should feel like a set of panels.
Why it is a history and not a process118 words
Nothing is numbered, nothing is counted, and there is no next step. The years are real dates rather than positions in a sequence, which is why they are plain paragraphs and not a core/list: an ordered list would renumber itself and would refuse a date.
It is not the other two patterns in this section. timeline-rail is six entries on a rail down ONE side, and reads as an index. timeline-decades is twenty packed single lines under four decade heads and no rail at all, and reads as a record. This one is six entries on both sides of a centre line, and the alternation is the whole idea. Same section, three different densities and three different readings.
How an entry is structured70 words
Each entry is three blocks in one group, in this order:
- a
core/paragraphholding the year, at display size; - a
core/heading(h3) holding the title, under 30 characters; - a
core/paragraphholding one or two sentences.
The group carries the entry's padding: top, bottom, and one horizontal side, the side facing the rule. It is the padding that spaces the entries, so the six borders can stay touching.
The variation115 words
crossing-plates(Crossed plates) moves the composition and nothing else. Each entry stops being bare copy against the rule and becomes a plate: a group with abase-chain ground, acurrentColor1px border and its own padding. The rule is untouched, still continuous, still on the centre, so it now threads between six panels rather than running beside six blocks of text. The entry padding drops from spacing-50 to spacing-30 because each plate now carries its own inset; the run-past at both ends is unchanged. It costs measure on a phone, because the plate's padding comes out of an already narrow half, which is why its horizontal inset is much smaller than its vertical one.
Notes97 words
- Core blocks only. No plugin, no script, no separator, no image.
- Every colour is a fallback chain ending on a guaranteed colour, and the rule is
currentColor. - Every heading states its own text colour, because a theme's heading element style beats an inherited group colour.
- The rule is a border on the
core/columnitself.core/columnhas border support at the 6.6 floor; an empty column with a border and no content is what WordPress's own editor writes for an empty column, and it is what makes the line continuous under a two-sided timeline.
Display type43 words
Off the theme's ladder on purpose, because the size is the composition:
- paragraph at clamp(1.625rem, 2.8vw, 2.75rem)
- body copy in the unstacked 50% plates (
crossing-plates) at clamp(0.9375rem, 1.05vw, 1.0625rem): onmediuma plate at 390 drops under 20 characters a line
The markup
Core block markup and nothing else. Copy it, then paste it straight into the block editor: WordPress reads the delimiters and rebuilds the blocks.
Fetching the markup…
Variation: Crossed plates
Fetching the markup…