Skip to content

Commit c4c87f5

Browse files
authored
feat(cv-v2): Mint Editorial colour Options + banded masthead + parity baselines (#78)
* feat(cv-v2): add Mint Editorial colour Options + banded masthead MintEditorial and MintEditorialLetter gain an Options colour API (accentColor, ruleColor, nameColor, headerBandColor) whose defaults reproduce the stock render exactly. headerBandColor paints a full-page-width header band from the top page edge down to the masthead rule, drawn page-1 only via a CanvasLayerNode so it costs no flow height and the CV stays two pages. The masthead-band geometry is pinned to measured constants, now guarded by smoke tests asserting the default masthead position and the banded-vs-bandless footprint stay in sync. * test(cv-v2): register Mint Editorial parity baselines + docs Registers mint_editorial and mint-editorial-letter in the CV and cover-letter visual parity suites with committed page baselines, documents the SkillBar and IconTextRow widgets in the v2 authoring catalog, and adds the Mint Editorial entry to the v1.6.5 CHANGELOG.
1 parent 0c072f1 commit c4c87f5

11 files changed

Lines changed: 729 additions & 44 deletions

File tree

CHANGELOG.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ follow semantic versioning; release dates are ISO 8601.
1111
template surface, including its isolated theme tokens, visual
1212
regression baselines, and reusable `Subheadline` /
1313
`SectionHeader.flatSpacedCaps` widget support.
14+
- Added the **Mint Editorial** template set: a two-page, two-column
15+
editorial CV preset `MintEditorial` (centred spaced-caps masthead with
16+
a full-width mint accent rule; sidebar contact / interests / education /
17+
expertise / skill-bars / social beside a profile / experience / awards /
18+
references main column) and its paired `MintEditorialLetter`, both on
19+
`CvTheme.mintEditorial()` and with visual regression baselines.
20+
- Added two reusable `cv/v2/widgets`: `SkillBar` (data-driven proficiency
21+
bar — spaced-caps label above a track with a level-positioned marker;
22+
no bar when the level is absent) and `IconTextRow` (inline icon + text
23+
row, optionally a single click target), with `WidgetSmokeTest` coverage.
24+
- Added optional proficiency levels to `SkillGroup` via the new
25+
`CvSkill` record and `SkillsSection.Builder.leveledGroup(...)`. Fully
26+
backward-compatible: name-only skills carry no level and every existing
27+
name-based renderer is unaffected.
28+
- Added `MintEditorial.Options` (and a matching `MintEditorialLetter.Options`)
29+
— an additive masthead colour API (accent, rule, name, and an optional
30+
full-width page-1 header band) whose defaults reproduce the stock render
31+
exactly, so the committed look and the parity baselines are unchanged.
1432

1533
### Public API
1634

docs/templates/v2-layered/authoring-presets.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ in `com.demcha.compose.document.templates.widgets`.
107107
| `SectionHeader.upperRule(host, title, theme, titleStyle, ruleColor, ruleWidth)` | Uppercase label with short rule below |
108108
| `SectionHeader.spacedCapsRule(host, title, theme, titleStyle, ruleColor, ruleWidth, ruleThickness, ruleMargin)` | Spaced-caps label with short rule below |
109109

110+
### `SkillBar` — data-driven proficiency bar
111+
112+
| Variant | Visual |
113+
|---|---|
114+
| `SkillBar.render(host, skill, trackWidth, theme)` | Spaced-caps skill label above a thin track with a level-positioned marker; renders the label with **no bar** when `skill.level()` is absent |
115+
116+
Reads the level from `CvSkill.level()` (`[0, 1]`); used by the Mint
117+
Editorial skills sidebar.
118+
119+
### `IconTextRow` — inline icon + text row
120+
121+
| Variant | Visual |
122+
|---|---|
123+
| `IconTextRow.render(host, icon, iconSize, text, style, link, margin)` | A glyph image followed by a label on one baseline; the whole row is a single click target when a `link` is supplied |
124+
125+
Used for the icon-led contact and social rows in sidebar CV layouts
126+
(Mint Editorial).
127+
110128
### Higher-order CV widgets
111129

112130
| Widget | Visual |
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.demcha.examples.templates.cv.v2;
2+
3+
import com.demcha.compose.GraphCompose;
4+
import com.demcha.compose.document.api.DocumentPageSize;
5+
import com.demcha.compose.document.api.DocumentSession;
6+
import com.demcha.compose.document.style.DocumentColor;
7+
import com.demcha.compose.document.templates.api.DocumentTemplate;
8+
import com.demcha.compose.document.templates.cv.v2.data.CvDocument;
9+
import com.demcha.compose.document.templates.cv.v2.presets.MintEditorial;
10+
import com.demcha.examples.support.ExampleDataFactory;
11+
import com.demcha.examples.support.ExampleOutputPaths;
12+
13+
import java.nio.file.Path;
14+
15+
/**
16+
* Renders the Mint Editorial CV against the rich "Rose Harris" showcase
17+
* dataset with a single <strong>custom colour</strong> via
18+
* {@link MintEditorial.Options} — a soft kraft-paper header band that fills
19+
* the whole masthead zone from the top page edge down to the mint rule. Only
20+
* {@code headerBandColor} is set; everything else stays default, so the dark
21+
* name, mint tagline, and mint full-width rule are unchanged and read cleanly
22+
* on the light tan band. This demonstrates the colour-customisation API; the
23+
* default-coloured render lives in {@code CvMintEditorialExample} and is left
24+
* untouched.
25+
*
26+
* <p>Output:
27+
* {@code examples/target/generated-pdfs/templates/cv/cv-mint-editorial-v2-custom.pdf}.</p>
28+
*/
29+
public final class CvMintEditorialCustomExample {
30+
31+
private CvMintEditorialCustomExample() {
32+
}
33+
34+
public static Path generate() throws Exception {
35+
Path outputFile = ExampleOutputPaths.prepare(
36+
"templates/cv", "cv-mint-editorial-v2-custom.pdf");
37+
CvDocument doc = ExampleDataFactory.mintEditorialShowcaseCv();
38+
39+
// Set ONLY the header band colour — a soft warm kraft-paper tan. Every
40+
// other knob stays default: dark ink name, mint tagline, mint
41+
// full-width rule. The dark name reads cleanly on the light tan band.
42+
MintEditorial.Options options = MintEditorial.Options.builder()
43+
.headerBandColor(DocumentColor.rgb(228, 217, 198)) // kraft-paper tan band
44+
.build();
45+
DocumentTemplate<CvDocument> template = MintEditorial.create(options);
46+
47+
float m = (float) MintEditorial.RECOMMENDED_MARGIN;
48+
try (DocumentSession document = GraphCompose.document(outputFile)
49+
.pageSize(DocumentPageSize.A4)
50+
.margin(m, m, m, m)
51+
.create()) {
52+
template.compose(document, doc);
53+
document.buildPdf();
54+
}
55+
return outputFile;
56+
}
57+
58+
public static void main(String[] args) throws Exception {
59+
System.out.println("Generated: " + generate());
60+
}
61+
}

0 commit comments

Comments
 (0)