Skip to content

feat(templates): add the Slate Orange masthead-and-rail CV preset - #629

Merged
DemchaAV merged 2 commits into
feature/template-promotionfrom
feat/slate-orange-preset
Aug 31, 2026
Merged

DemchaAV merged 2 commits into
feature/template-promotionfrom
feat/slate-orange-preset

Conversation

@DemchaAV

Copy link
Copy Markdown
Owner

Why

The next CV in the promotion queue, and the densest one yet: a full-bleed slate masthead over a two-column body, ten marked competencies, rated languages, a dated experience rail and a credentials footer. It is also the first design in the family that shows a language's rating and names it on the same line, which is why it needed CvSkill.note (#628) before it could land.

What

cv.presets.SlateOrange, composed from six package-private files — the measured geometry and type scale, the icon loader, the idioms the sheet repeats, and one per region.

Three things worth naming.

The fills that reach a paper edge are page backgrounds. The slate band, the orange monogram tile and the two column dividers are PageBackgroundFills rather than section fills or line nodes: a fill on a section is bounded by its content and would stop short of the edge, while a page background takes its geometry from the canvas.

Every horizontal pair inside a body column is a table. A row cannot nest in a row cell and both columns are cells of the body row, so mark-and-label, language-and-rating, role-and-dates and the two credential columns are all tables with fixed widths; where a cell needs several stacked lines it holds a single-column table of its own, because a cell holds one node. The experience rail is the left border of each entry rather than a drawn line, so it stretches to whatever height the entry turns out to have.

The languages draw both channels of a rated skill — the discs from level(), the words beside them from note(). A skill with no level draws no discs; one with no note leaves that column empty rather than inventing a wording.

Seven berths reach their sections by title, including a specialism berth whose body is drawn and whose title is not. As on the presets before it, a link is drawn as its own label with the address behind it — the one deliberate departure from the ported sheet, measured at 2 100 of 2 173 720 pixels — and a role or a degree becomes a link when its entry carries one.

Also here: the example (cv-slate-orange-v2), its showcase row and its committed preview.

Tests

./mvnw -B -ntp clean verify -pl :graph-compose-core,:graph-compose-render-pdf,:graph-compose-render-docx,:graph-compose-render-pptx,:graph-compose-templates,:graph-compose-testing,:graph-compose-qa,:graph-compose-coverage -am — BUILD SUCCESS, 1000 tests.

  • SlateOrangeSmokeTest (14) — identity, the canonical render, every block's text, the monogram and the strip, a language with and without its wording, the contact and link targets, a link showing its label, a linked role and degree, an unknown mark reported as a data error, an achievement with no mark falling back to the trophy, a document with nothing but an identity, an identity with no links, and the refusal of a CV taller than the sheet.
  • SlateOrangeLayoutSnapshotTest (1) and SlateOrangeVisualParityTest (1).

The port was proven before the gates were written: the preset rendered against the bundle's own fixture differs by 0 of 2 173 720 pixels, with 71 of 71 layout nodes identical in geometry — the only differences being the four node names the promotion deliberately changes.

One finding worth recording, as with the last one: this bundle does not reproduce its own published preview — 12 262 pixels differ, identically on the engine it was cut against and on this one, so the engine is not the cause. The text is identical and the difference is sub-pixel positioning, so the preview predates a small geometry revision of the template. The published source is self-consistent and is what was ported.

Stacked on #628, which it needs for CvSkill.note.

A rated skill could say how much — a number in [0, 1] a preset draws as dots
or a meter — or it could say it in words by not being a skill at all and
living in a RowsSection instead. It could not say both, which is why
CharcoalGold sets its languages as rows: that design writes "Native" and
"B2 – Upper Intermediate" out, and a number could not carry them back.

A design that shows a rating and names it in the same line had nowhere to go.
CvSkill now carries `note`, a plain string blank when absent, reachable
through CvSkill.of(name, level, note). The two channels stay separate because
a number cannot carry a wording and a wording cannot be measured into a meter;
a preset draws whichever it has room for, or both.

The two-argument constructor and both existing factories are kept explicitly,
so existing calls compile and link unchanged and every skill built through
them still carries no note.
A one-page sheet built as a full-bleed slate band over a two-column body: an
orange monogram tile beside the name, the role line and a tracked specialism
strip, with the contact lines across an orange hairline; then a narrow column
of marked competencies, trophied achievements, rated languages and closing
facts, beside a wide column carrying the profile, the roles held on a rail,
and a credentials footer.

It ports a published standalone template onto the existing CvDocument, and is
the first preset to use CvSkill.note: its language rows show a rating and name
it on the same line, which is the pair the model could not carry before.

The four fills that reach a paper edge — the slate band, the orange tile and
the two column dividers — are page backgrounds rather than section fills,
because a fill on a section is bounded by its content. Every horizontal pair
inside a body column is a table with fixed widths: a row cannot nest in a row
cell and both columns are cells, and where a cell needs several stacked lines
it holds a single-column table of its own.

Seven berths reach their sections by title, including a specialism berth whose
body is drawn and whose title is not. As on the presets before it a link is
drawn as its own label with the address behind it, the one deliberate
departure from the ported sheet at 2,100 of 2,173,720 pixels, and a role or a
degree becomes a link when its entry carries one.

Guarded by a smoke test, an exact layout snapshot and a pixel-parity gate; the
examples showcase gains `cv-slate-orange-v2`.
@DemchaAV
DemchaAV merged commit 6a519a2 into feature/template-promotion Aug 31, 2026
12 checks passed
@DemchaAV
DemchaAV deleted the feat/slate-orange-preset branch August 31, 2026 17:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant