feat(templates): add the SerifHeadline two-column CV preset - #619
Merged
DemchaAV merged 1 commit intoAug 31, 2026
Merged
Conversation
| if (hasBody) { | ||
| page.addRow("BodyColumns", row -> { | ||
| row.spacing(0); | ||
| row.gap(0); |
| static void compose(PageFlowBuilder page, CvIdentity identity, ParagraphSection summary) { | ||
| page.addRow("Masthead", row -> { | ||
| row.spacing(0); | ||
| row.gap(0); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The third CV bundle in the queue is the one that stops being a sidebar. It is a two-column editorial sheet with a serif masthead, a timeline of roles beside grouped skill meters, and two full-width bands of marked cards closing it — 235 laid-out nodes against the 87 and 158 of its predecessors.
It is also the one whose geometry is not a set of numbers somebody typed. The design was drawn on a 1024-pixel grid and every distance in it is that grid put through a scale, with each vertical gap expressed as the ink the drawing shows rather than the margin a line box needs. Porting it meant porting that arithmetic, not its results.
What changed
cv/presets/SerifHeadline— aDocumentTemplate<CvDocument>viacreate(), split for the 500-LOC rule into package-privateSerifHeadlineStyles(the grid, the type metrics and the gap arithmetic),SerifHeadlineWidgets(the heading, the plate, the N-column band),SerifHeadlineMasthead,SerifHeadlineMain,SerifHeadlineAside,SerifHeadlineClosing,SerifHeadlineTextandSerifHeadlineIcons.gap(inkPx, blankAbove, blankBelow)states a distance as the white between letters and subtracts what the two line boxes already contribute; heights carry a compression factor on top of the width scale, because the drawing is proportionally taller than A4. Freezing the results as literals would have been unmaintainable the first time a type size moved.CvEntry.icon(); the vocabulary is this preset's own and an unknown token is reported as a data error listing the set. The certification medal is chrome, not data. The employer's city and the campus come fromCvEntry.place().templates/cv/serif-headline/icons/.Verification
Full reactor gate (the eight CI modules) → BUILD SUCCESS; the CV preset suites 30/30; examples suite 77/77 including
CommittedAssetDriftTestwith the new preview;javadoc:javadoc→ BUILD SUCCESS with no warning naming a new file.Port parity, verified against the published template itself: the preset fed the template's own fixture is pixel-identical to the standalone render — 0 / 2,173,720 differing pixels, and the layout snapshot matches node for node — 235 of 235, same names, zero geometry delta. The bundle's geometry is the same on its pinned 2.2.0 and on this branch (235/235 nodes, zero deltas > 0.01pt); the two engines differ only by the released ligature fix (#601), so the current-engine render is the parity target.
Notes
AtomicNodeTooLargeExceptionrather than flowing or dropping entries — the same contract the two sidebar presets landed with, documented on the class, inusing-templates.md, and pinned by a test.trackedWidthis an estimate, so a heading long enough to make its trailing rule overlap the letters would not go red. The margin errs short and the snapshot freezes the fixture's rules; the method says as much.Lane: canonical (templates.cv.presets + qa + examples) — no engine changes, no model changes (those landed in #618).