From 92ce897fca927355e6f80c320ad169c4476d8cfe Mon Sep 17 00:00:00 2001
From: DemchaAV
Date: Sat, 30 May 2026 03:20:52 +0100
Subject: [PATCH 1/2] 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.
---
.../cv/v2/CvMintEditorialCustomExample.java | 61 ++++
.../v2/presets/MintEditorialLetter.java | 241 +++++++++++--
.../cv/v2/presets/MintEditorial.java | 327 ++++++++++++++++--
.../cv/v2/presets/MintEditorialSmokeTest.java | 98 ++++++
4 files changed, 685 insertions(+), 42 deletions(-)
create mode 100644 examples/src/main/java/com/demcha/examples/templates/cv/v2/CvMintEditorialCustomExample.java
diff --git a/examples/src/main/java/com/demcha/examples/templates/cv/v2/CvMintEditorialCustomExample.java b/examples/src/main/java/com/demcha/examples/templates/cv/v2/CvMintEditorialCustomExample.java
new file mode 100644
index 00000000..fd2a9e79
--- /dev/null
+++ b/examples/src/main/java/com/demcha/examples/templates/cv/v2/CvMintEditorialCustomExample.java
@@ -0,0 +1,61 @@
+package com.demcha.examples.templates.cv.v2;
+
+import com.demcha.compose.GraphCompose;
+import com.demcha.compose.document.api.DocumentPageSize;
+import com.demcha.compose.document.api.DocumentSession;
+import com.demcha.compose.document.style.DocumentColor;
+import com.demcha.compose.document.templates.api.DocumentTemplate;
+import com.demcha.compose.document.templates.cv.v2.data.CvDocument;
+import com.demcha.compose.document.templates.cv.v2.presets.MintEditorial;
+import com.demcha.examples.support.ExampleDataFactory;
+import com.demcha.examples.support.ExampleOutputPaths;
+
+import java.nio.file.Path;
+
+/**
+ * Renders the Mint Editorial CV against the rich "Rose Harris" showcase
+ * dataset with a single custom colour via
+ * {@link MintEditorial.Options} — a soft kraft-paper header band that fills
+ * the whole masthead zone from the top page edge down to the mint rule. Only
+ * {@code headerBandColor} is set; everything else stays default, so the dark
+ * name, mint tagline, and mint full-width rule are unchanged and read cleanly
+ * on the light tan band. This demonstrates the colour-customisation API; the
+ * default-coloured render lives in {@code CvMintEditorialExample} and is left
+ * untouched.
+ *
+ * Output:
+ * {@code examples/target/generated-pdfs/templates/cv/cv-mint-editorial-v2-custom.pdf}.
+ */
+public final class CvMintEditorialCustomExample {
+
+ private CvMintEditorialCustomExample() {
+ }
+
+ public static Path generate() throws Exception {
+ Path outputFile = ExampleOutputPaths.prepare(
+ "templates/cv", "cv-mint-editorial-v2-custom.pdf");
+ CvDocument doc = ExampleDataFactory.mintEditorialShowcaseCv();
+
+ // Set ONLY the header band colour — a soft warm kraft-paper tan. Every
+ // other knob stays default: dark ink name, mint tagline, mint
+ // full-width rule. The dark name reads cleanly on the light tan band.
+ MintEditorial.Options options = MintEditorial.Options.builder()
+ .headerBandColor(DocumentColor.rgb(228, 217, 198)) // kraft-paper tan band
+ .build();
+ DocumentTemplate template = MintEditorial.create(options);
+
+ float m = (float) MintEditorial.RECOMMENDED_MARGIN;
+ try (DocumentSession document = GraphCompose.document(outputFile)
+ .pageSize(DocumentPageSize.A4)
+ .margin(m, m, m, m)
+ .create()) {
+ template.compose(document, doc);
+ document.buildPdf();
+ }
+ return outputFile;
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.out.println("Generated: " + generate());
+ }
+}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/v2/presets/MintEditorialLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/v2/presets/MintEditorialLetter.java
index bd404f49..5e356fcf 100644
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/v2/presets/MintEditorialLetter.java
+++ b/src/main/java/com/demcha/compose/document/templates/coverletter/v2/presets/MintEditorialLetter.java
@@ -2,7 +2,13 @@
import com.demcha.compose.document.api.DocumentSession;
import com.demcha.compose.document.dsl.PageFlowBuilder;
+import com.demcha.compose.document.dsl.ParagraphBuilder;
import com.demcha.compose.document.dsl.SectionBuilder;
+import com.demcha.compose.document.dsl.ShapeBuilder;
+import com.demcha.compose.document.node.DocumentNode;
+import com.demcha.compose.document.node.ParagraphNode;
+import com.demcha.compose.document.node.TextAlign;
+import com.demcha.compose.document.style.ClipPolicy;
import com.demcha.compose.document.style.DocumentColor;
import com.demcha.compose.document.style.DocumentInsets;
import com.demcha.compose.document.style.DocumentTextDecoration;
@@ -11,6 +17,7 @@
import com.demcha.compose.document.templates.coverletter.v2.components.LetterBody;
import com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument;
import com.demcha.compose.document.templates.cv.v2.components.CvTextStyles;
+import com.demcha.compose.document.templates.cv.v2.components.TextOrnaments;
import com.demcha.compose.document.templates.cv.v2.data.CvIdentity;
import com.demcha.compose.document.templates.cv.v2.theme.CvTheme;
import com.demcha.compose.document.templates.cv.v2.widgets.Headline;
@@ -30,6 +37,11 @@
* CV, so the CV and the letter read as one matched set. The CV's two-column
* sidebar grids are a CV-body concern and are intentionally not part of the
* letter.
+ *
+ * The same {@link Options} colour knobs as the paired
+ * {@link com.demcha.compose.document.templates.cv.v2.presets.MintEditorial}
+ * preset recolour the letter masthead (accent, rule, name, optional header
+ * band), with identical defaults so the matched set stays in sync.
*/
public final class MintEditorialLetter {
@@ -42,33 +54,140 @@ public final class MintEditorialLetter {
/** Recommended symmetric page margin (in points). Matches the CV preset. */
public static final double RECOMMENDED_MARGIN = 48.0;
+ // Banded-masthead canvas geometry — mirrors the CV preset so the matched
+ // set's masthead is identical, and reproduces the letter's own DEFAULT
+ // (bandless) masthead positions so the banded render only adds a fill
+ // behind an otherwise-unchanged masthead.
+
+ /** Canvas flow footprint (points) — matches the CV masthead footprint. */
+ private static final double MASTHEAD_CANVAS_HEIGHT = 143.76;
+
+ /** Canvas-local y (points) of the masthead name — matches the default top. */
+ private static final double MASTHEAD_NAME_Y = 48.0;
+
+ /** Canvas-local y (points) of the masthead tagline — matches the default top. */
+ private static final double MASTHEAD_TAGLINE_Y = 87.4;
+
+ /** Canvas-local y (points) of the masthead rule — matches the default top. */
+ private static final double MASTHEAD_RULE_Y = 123.76;
+
private MintEditorialLetter() {
}
- /** Builds the letter with its Mint Editorial theme. */
+ /** Builds the letter with its Mint Editorial theme and default colours. */
public static DocumentTemplate create() {
- return create(CvTheme.mintEditorial());
+ return create(CvTheme.mintEditorial(), Options.defaults());
}
/**
- * Builds the letter with a caller-supplied theme (share the paired CV's
- * theme instance for a guaranteed visual match).
+ * Builds the letter with a caller-supplied theme and default colours
+ * (share the paired CV's theme instance for a guaranteed visual match).
*/
public static DocumentTemplate create(CvTheme theme) {
+ return create(theme, Options.defaults());
+ }
+
+ /** Builds the letter with its Mint Editorial theme and explicit colours. */
+ public static DocumentTemplate create(Options options) {
+ return create(CvTheme.mintEditorial(), options);
+ }
+
+ /**
+ * Builds the letter with a caller-supplied theme and explicit colour
+ * {@link Options}. Pass the same {@code Options} as the paired CV preset
+ * so the recoloured masthead matches.
+ */
+ public static DocumentTemplate create(CvTheme theme,
+ Options options) {
Objects.requireNonNull(theme, "theme");
- return new Template(theme);
+ Objects.requireNonNull(options, "options");
+ return new Template(theme, options);
+ }
+
+ /**
+ * Mint Editorial letter masthead colour knobs — same shape and defaults as
+ * {@code MintEditorial.Options}. Every {@code null} field reproduces the
+ * stock render.
+ *
+ * @param accentColor mint accent for the tagline; {@code null} →
+ * {@code theme.palette().banner()}
+ * @param ruleColor masthead rule colour; {@code null} → the resolved
+ * {@code accentColor}
+ * @param nameColor masthead name colour; {@code null} →
+ * {@code theme.palette().ink()}
+ * @param headerBandColor optional full-width band behind the masthead;
+ * {@code null} → no band
+ */
+ public record Options(DocumentColor accentColor,
+ DocumentColor ruleColor,
+ DocumentColor nameColor,
+ DocumentColor headerBandColor) {
+
+ public static Options defaults() {
+ return new Options(null, null, null, null);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+ private DocumentColor accentColor;
+ private DocumentColor ruleColor;
+ private DocumentColor nameColor;
+ private DocumentColor headerBandColor;
+
+ private Builder() {
+ }
+
+ public Builder accentColor(DocumentColor value) {
+ this.accentColor = value;
+ return this;
+ }
+
+ public Builder ruleColor(DocumentColor value) {
+ this.ruleColor = value;
+ return this;
+ }
+
+ public Builder nameColor(DocumentColor value) {
+ this.nameColor = value;
+ return this;
+ }
+
+ public Builder headerBandColor(DocumentColor value) {
+ this.headerBandColor = value;
+ return this;
+ }
+
+ public Options build() {
+ return new Options(accentColor, ruleColor, nameColor,
+ headerBandColor);
+ }
+ }
}
private static final class Template implements DocumentTemplate {
private final CvTheme theme;
private final DocumentColor accent;
+ private final DocumentColor ruleColor;
+ private final DocumentColor nameColor;
+ private final DocumentColor headerBandColor;
- Template(CvTheme theme) {
+ Template(CvTheme theme, Options options) {
this.theme = theme;
- // Same accent source as the paired CV preset — the palette
- // banner slot carries the mint accent.
- this.accent = theme.palette().banner();
+ // Same accent source + Options defaults as the paired CV preset.
+ this.accent = options.accentColor() != null
+ ? options.accentColor()
+ : theme.palette().banner();
+ this.ruleColor = options.ruleColor() != null
+ ? options.ruleColor()
+ : this.accent;
+ this.nameColor = options.nameColor() != null
+ ? options.nameColor()
+ : theme.palette().ink();
+ this.headerBandColor = options.headerBandColor();
}
@Override
@@ -97,13 +216,19 @@ public void compose(DocumentSession document, CoverLetterDocument doc) {
.spacing(theme.spacing().pageFlowSpacing());
flow.addSection("CoverLetterV2MintEditorialHeader",
- section -> addMasthead(section, doc.identity()));
- flow.addLine(line -> line
- .name("CoverLetterV2MintEditorialHeaderRule")
- .horizontal(pageWidth)
- .color(accent)
- .thickness(theme.spacing().accentRuleWidth())
- .margin(new DocumentInsets(8, -ruleBleed, 14, -ruleBleed)));
+ section -> addMasthead(section, doc.identity(), pageWidth,
+ ruleBleed));
+ if (headerBandColor == null) {
+ // Stock masthead rule. In banded mode the rule is drawn flush at
+ // the band's bottom edge inside the header canvas, so the
+ // separate flow rule is suppressed (no doubled line).
+ flow.addLine(line -> line
+ .name("CoverLetterV2MintEditorialHeaderRule")
+ .horizontal(pageWidth)
+ .color(ruleColor)
+ .thickness(theme.spacing().accentRuleWidth())
+ .margin(new DocumentInsets(8, -ruleBleed, 14, -ruleBleed)));
+ }
flow.addSection("CoverLetterV2MintEditorialBody", host ->
LetterBody.render(host, doc, theme));
@@ -113,17 +238,93 @@ public void compose(DocumentSession document, CoverLetterDocument doc) {
/**
* Centred spaced-caps name + mint accent tagline — the identical
- * masthead the {@code MintEditorial} CV preset renders, so the
- * matched set never forks the header treatment.
+ * masthead the {@code MintEditorial} CV preset renders, so the matched
+ * set never forks the header treatment. With default colours and no
+ * band the output is byte-identical to the pre-Options render.
*/
- private void addMasthead(SectionBuilder section, CvIdentity identity) {
- Headline.spacedCentered(section, identity.name(), theme);
+ private void addMasthead(SectionBuilder section, CvIdentity identity,
+ double pageWidth, double ruleBleed) {
+ if (headerBandColor != null) {
+ addBandedMasthead(section, identity, pageWidth, ruleBleed);
+ } else {
+ addPlainMasthead(section, identity);
+ }
+ }
+
+ private void addPlainMasthead(SectionBuilder section, CvIdentity identity) {
+ // Style-override variant so only the name colour can change.
+ Headline.render(section, identity.name(), theme,
+ TextAlign.CENTER, true, mastheadNameStyle());
String jobTitle = identity.jobTitle();
if (jobTitle != null && !jobTitle.isBlank()) {
Subheadline.centeredSpacedCaps(section, jobTitle, taglineStyle());
}
}
+ /**
+ * Banded masthead: the whole masthead zone is one
+ * {@code CanvasLayerNode} (controlled absolute placement), mirroring the
+ * paired CV preset. The band fills the canvas (page top edge → rule),
+ * the canvas is bled to the page edges via negative margins, and the
+ * rule sits flush at the band's bottom edge. The canvas reserves only
+ * {@value #MASTHEAD_CANVAS_HEIGHT}pt of flow, so the band adds no extra
+ * flow height. See {@code MintEditorial.addBandedHeader} for the full
+ * rationale (including why the band fills the canvas rather than
+ * overflowing a child upward).
+ */
+ private void addBandedMasthead(SectionBuilder section,
+ CvIdentity identity, double pageWidth,
+ double ruleBleed) {
+ double canvasH = MASTHEAD_CANVAS_HEIGHT;
+ double ruleThickness = theme.spacing().accentRuleWidth();
+ double bandHeight = MASTHEAD_RULE_Y + ruleThickness;
+
+ DocumentNode band = new ShapeBuilder()
+ .name("CoverLetterV2MintEditorialHeaderBand")
+ .size(pageWidth, bandHeight)
+ .fillColor(headerBandColor)
+ .build();
+ DocumentNode rule = new ShapeBuilder()
+ .name("CoverLetterV2MintEditorialHeaderRule")
+ .size(pageWidth, ruleThickness)
+ .fillColor(ruleColor)
+ .build();
+ ParagraphNode name = new ParagraphBuilder()
+ .name("CoverLetterV2MintEditorialHeaderName")
+ .text(TextOrnaments.spacedUpper(identity.name().full()))
+ .textStyle(mastheadNameStyle())
+ .align(TextAlign.CENTER)
+ .build();
+ String jobTitle = identity.jobTitle();
+ ParagraphNode tagline = jobTitle != null && !jobTitle.isBlank()
+ ? new ParagraphBuilder()
+ .name("CoverLetterV2MintEditorialHeaderTagline")
+ .text(TextOrnaments.spacedUpper(jobTitle))
+ .textStyle(taglineStyle())
+ .align(TextAlign.CENTER)
+ .build()
+ : null;
+
+ section.addCanvas(pageWidth, canvasH, canvas -> {
+ canvas.name("CoverLetterV2MintEditorialHeaderCanvas")
+ .clipPolicy(ClipPolicy.OVERFLOW_VISIBLE)
+ .margin(new DocumentInsets(-ruleBleed, -ruleBleed, 0,
+ -ruleBleed))
+ .position(band, 0.0, 0.0)
+ .position(rule, 0.0, MASTHEAD_RULE_Y)
+ .position(name, 0.0, MASTHEAD_NAME_Y);
+ if (tagline != null) {
+ canvas.position(tagline, 0.0, MASTHEAD_TAGLINE_Y);
+ }
+ });
+ }
+
+ private DocumentTextStyle mastheadNameStyle() {
+ return CvTextStyles.of(theme.typography().headlineFont(),
+ theme.typography().sizeHeadline(),
+ DocumentTextDecoration.DEFAULT, nameColor);
+ }
+
private DocumentTextStyle taglineStyle() {
return CvTextStyles.of(theme.typography().headlineFont(),
theme.typography().sizeContact(),
diff --git a/src/main/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorial.java b/src/main/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorial.java
index 4f455289..053422e1 100644
--- a/src/main/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorial.java
+++ b/src/main/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorial.java
@@ -1,12 +1,17 @@
package com.demcha.compose.document.templates.cv.v2.presets;
import com.demcha.compose.document.api.DocumentSession;
+import com.demcha.compose.document.dsl.PageFlowBuilder;
import com.demcha.compose.document.dsl.ParagraphBuilder;
import com.demcha.compose.document.dsl.SectionBuilder;
+import com.demcha.compose.document.dsl.ShapeBuilder;
import com.demcha.compose.document.image.DocumentImageData;
import com.demcha.compose.document.node.DocumentLinkOptions;
+import com.demcha.compose.document.node.DocumentNode;
import com.demcha.compose.document.node.ParagraphNode;
+import com.demcha.compose.document.node.ShapeNode;
import com.demcha.compose.document.node.TextAlign;
+import com.demcha.compose.document.style.ClipPolicy;
import com.demcha.compose.document.style.DocumentColor;
import com.demcha.compose.document.style.DocumentInsets;
import com.demcha.compose.document.style.DocumentStroke;
@@ -172,6 +177,35 @@ public final class MintEditorial {
/** Expertise badge edge length (points). */
private static final double BADGE_SIZE = 36.0;
+ // Banded-masthead canvas geometry. These values reproduce the DEFAULT
+ // (bandless) masthead flow positions exactly — name baseline, tagline
+ // baseline, and rule y — measured from the stock render at the canonical
+ // 48pt page margin. The canvas top is bled to the page top edge (y=0) via a
+ // negative margin, so a canvas-local y equals the page-absolute top edge in
+ // points; the constants therefore equal the default page-absolute tops. The
+ // band fills the canvas from y=0 down to the rule's bottom, and the masthead
+ // (name/tagline/rule) renders at the same positions whether or not a band is
+ // present — the band only adds a tan fill behind it.
+ //
+ // These are package-private (not private) so MintEditorialSmokeTest can
+ // assert them against the live default masthead positions — see its
+ // band_constants_match_default_masthead guard, which fails if a future
+ // typography / spacing / margin change moves the masthead and silently
+ // invalidates these hand-measured coordinates.
+
+ /** Canvas flow footprint (points) — sized so the page-1 row starts at the
+ * same y as the default render. */
+ static final double MASTHEAD_CANVAS_HEIGHT = 143.76;
+
+ /** Canvas-local y (points) of the masthead name — matches the default top. */
+ static final double MASTHEAD_NAME_Y = 48.0;
+
+ /** Canvas-local y (points) of the masthead tagline — matches the default top. */
+ static final double MASTHEAD_TAGLINE_Y = 87.4;
+
+ /** Canvas-local y (points) of the masthead rule — matches the default top. */
+ static final double MASTHEAD_RULE_Y = 123.76;
+
private static final String ICON_ROOT = "/templates/cv/mint-editorial/icons/";
private static final Map ICON_CACHE = new ConcurrentHashMap<>();
@@ -195,30 +229,133 @@ public final class MintEditorial {
private MintEditorial() {
}
- /** Builds the preset with its Mint Editorial theme. */
+ /** Builds the preset with its Mint Editorial theme and default colours. */
public static DocumentTemplate create() {
- return create(CvTheme.mintEditorial());
+ return create(CvTheme.mintEditorial(), Options.defaults());
}
/**
- * Builds the preset with a caller-supplied theme (share the paired
- * cover letter's theme instance for a guaranteed visual match).
+ * Builds the preset with a caller-supplied theme and default colours
+ * (share the paired cover letter's theme instance for a guaranteed
+ * visual match).
*/
public static DocumentTemplate create(CvTheme theme) {
+ return create(theme, Options.defaults());
+ }
+
+ /**
+ * Builds the preset with its Mint Editorial theme and explicit colour
+ * {@link Options}.
+ */
+ public static DocumentTemplate create(Options options) {
+ return create(CvTheme.mintEditorial(), options);
+ }
+
+ /**
+ * Builds the preset with a caller-supplied theme and explicit colour
+ * {@link Options}. Use this to recolour the masthead (accent, rule,
+ * name, optional header band) without forking the theme.
+ */
+ public static DocumentTemplate create(CvTheme theme,
+ Options options) {
Objects.requireNonNull(theme, "theme");
- return new Template(theme);
+ Objects.requireNonNull(options, "options");
+ return new Template(theme, options);
+ }
+
+ /**
+ * Mint Editorial masthead colour knobs. Every {@code null} field falls
+ * back to a default that reproduces the stock render exactly, so an
+ * {@link #defaults()} instance leaves the committed look unchanged.
+ *
+ * @param accentColor mint accent used for the centred tagline and
+ * every spaced-caps section heading; {@code null}
+ * → {@code theme.palette().banner()}
+ * @param ruleColor full-width masthead rule colour, independent of
+ * the accent; {@code null} → the resolved
+ * {@code accentColor} (so unset = today's look)
+ * @param nameColor masthead name text colour; {@code null} →
+ * {@code theme.palette().ink()}
+ * @param headerBandColor optional full-page-width colour band painted
+ * behind the masthead on page 1 only;
+ * {@code null} → no band (white header)
+ */
+ public record Options(DocumentColor accentColor,
+ DocumentColor ruleColor,
+ DocumentColor nameColor,
+ DocumentColor headerBandColor) {
+
+ public static Options defaults() {
+ return new Options(null, null, null, null);
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static final class Builder {
+ private DocumentColor accentColor;
+ private DocumentColor ruleColor;
+ private DocumentColor nameColor;
+ private DocumentColor headerBandColor;
+
+ private Builder() {
+ }
+
+ public Builder accentColor(DocumentColor value) {
+ this.accentColor = value;
+ return this;
+ }
+
+ public Builder ruleColor(DocumentColor value) {
+ this.ruleColor = value;
+ return this;
+ }
+
+ public Builder nameColor(DocumentColor value) {
+ this.nameColor = value;
+ return this;
+ }
+
+ public Builder headerBandColor(DocumentColor value) {
+ this.headerBandColor = value;
+ return this;
+ }
+
+ public Options build() {
+ return new Options(accentColor, ruleColor, nameColor,
+ headerBandColor);
+ }
+ }
}
private static final class Template implements DocumentTemplate {
private final CvTheme theme;
+ /** Accent for the tagline + section headings (defaults to mint). */
private final DocumentColor accent;
-
- Template(CvTheme theme) {
+ /** Masthead rule colour (defaults to the accent). */
+ private final DocumentColor ruleColor;
+ /** Masthead name colour (defaults to ink). */
+ private final DocumentColor nameColor;
+ /** Optional page-1 header band; null = no band (white header). */
+ private final DocumentColor headerBandColor;
+
+ Template(CvTheme theme, Options options) {
this.theme = theme;
// Mint carries its accent in the palette banner slot — single
- // source shared with the paired cover letter.
- this.accent = theme.palette().banner();
+ // source shared with the paired cover letter. Each Options knob
+ // defaults to the value that reproduces the stock render.
+ this.accent = options.accentColor() != null
+ ? options.accentColor()
+ : theme.palette().banner();
+ this.ruleColor = options.ruleColor() != null
+ ? options.ruleColor()
+ : this.accent;
+ this.nameColor = options.nameColor() != null
+ ? options.nameColor()
+ : theme.palette().ink();
+ this.headerBandColor = options.headerBandColor();
}
@Override
@@ -268,18 +405,25 @@ public void compose(DocumentSession document, CvDocument doc) {
List experiencePage2 = experienceEntries.stream()
.skip(EXPERIENCE_PAGE_ONE).toList();
- document.dsl()
+ PageFlowBuilder flow = document.dsl()
.pageFlow()
.name("CvV2MintEditorialRoot")
.spacing(theme.spacing().pageFlowSpacing())
.addSection("CvV2MintEditorialHeader",
- section -> addHeader(section, identity))
- .addLine(line -> line
- .name("CvV2MintEditorialHeaderRule")
- .horizontal(pageWidth)
- .color(accent)
- .thickness(theme.spacing().accentRuleWidth())
- .margin(new DocumentInsets(8, -ruleBleed, 14, -ruleBleed)))
+ section -> addHeader(section, identity, pageWidth, ruleBleed));
+ if (headerBandColor == null) {
+ // Stock masthead rule, full page width. When a band is present
+ // the rule is drawn flush at the band's bottom edge inside the
+ // header canvas instead (see addBandedHeader), so the separate
+ // flow rule is suppressed to avoid a doubled line.
+ flow.addLine(line -> line
+ .name("CvV2MintEditorialHeaderRule")
+ .horizontal(pageWidth)
+ .color(ruleColor)
+ .thickness(theme.spacing().accentRuleWidth())
+ .margin(new DocumentInsets(8, -ruleBleed, 14, -ruleBleed)));
+ }
+ flow
.addRow("CvV2MintEditorialPageOne", row -> {
row.spacing(COLUMN_GAP).weights(SIDEBAR_WEIGHT, MAIN_WEIGHT);
row.addSection("CvV2MintEditorialPageOneSidebar", sidebar -> {
@@ -314,17 +458,121 @@ public void compose(DocumentSession document, CvDocument doc) {
// -- Header --------------------------------------------------------
- private void addHeader(SectionBuilder section, CvIdentity identity) {
- // Headline.spacedCentered sets the section's spacing + padding;
- // it renders the centred spaced-caps name as the page's loudest
- // element. The tagline follows in the mint accent.
- Headline.spacedCentered(section, identity.name(), theme);
+ private void addHeader(SectionBuilder section, CvIdentity identity,
+ double pageWidth, double ruleBleed) {
+ if (headerBandColor != null) {
+ addBandedHeader(section, identity, pageWidth, ruleBleed);
+ } else {
+ addPlainHeader(section, identity);
+ }
+ }
+
+ /**
+ * Stock masthead: centred spaced-caps name (in {@code nameColor}) over
+ * a centred accent tagline, no background band. When
+ * {@code nameColor == theme.palette().ink()} the explicit style equals
+ * {@code theme.headlineStyle()}, so the default render is byte-identical
+ * to the pre-Options output.
+ */
+ private void addPlainHeader(SectionBuilder section, CvIdentity identity) {
+ // Render the name through Headline's style-override variant so only
+ // the colour can change — alignment, spaced-caps transform, font and
+ // size all stay exactly as Headline.spacedCentered produced them.
+ Headline.render(section, identity.name(), theme,
+ TextAlign.CENTER, true, mastheadNameStyle());
String jobTitle = identity.jobTitle();
if (jobTitle != null && !jobTitle.isBlank()) {
Subheadline.centeredSpacedCaps(section, jobTitle, taglineStyle());
}
}
+ /**
+ * Banded masthead (page 1 only): the whole masthead zone is one
+ * {@code CanvasLayerNode} (controlled absolute placement, the v1.6
+ * free-canvas primitive) with {@link ClipPolicy#OVERFLOW_VISIBLE}. The
+ * canvas reserves only {@value #MASTHEAD_CANVAS_HEIGHT}pt in the flow —
+ * its declared height — so the masthead footprint stays small and the
+ * dense page-1 row still fits, keeping the document at two pages.
+ *
+ * Inside the canvas (origin top-left, y down):
+ *
+ * - the band rectangle is positioned at {@code (-ruleBleed,
+ * -ruleBleed)} and sized {@code pageWidth × (ruleBleed +
+ * canvasHeight)}, so — because overflow is visible — it bleeds up
+ * to the top page edge, out to both side edges (full width), and
+ * down to the canvas bottom;
+ * - a thin rule sits flush at the band's bottom edge, reading as the
+ * band's underline (the separate flow rule is suppressed in this
+ * mode, see {@code compose});
+ * - the centred name (in {@code nameColor}) and tagline (in
+ * {@code accentColor}) render on top.
+ *
+ *
+ * The band consumes no extra flow height because the canvas footprint
+ * is fixed and the overflow draws outside it. Page 2 is untouched: the
+ * header canvas is the first page-flow child, so it lives on page 1
+ * only — no {@code pageBackgrounds} (which would repeat on page 2).
+ */
+ private void addBandedHeader(SectionBuilder section, CvIdentity identity,
+ double pageWidth, double ruleBleed) {
+ double canvasH = MASTHEAD_CANVAS_HEIGHT;
+ double ruleThickness = theme.spacing().accentRuleWidth();
+ // Band runs from the top page edge down to the rule's bottom edge.
+ double bandHeight = MASTHEAD_RULE_Y + ruleThickness;
+
+ // The masthead (name / tagline / rule) is positioned at the EXACT
+ // default flow coordinates, so the banded and bandless renders share
+ // identical masthead geometry — only the tan fill behind it is new.
+ // The band fills the canvas from y=0 to the rule bottom; no child
+ // overflows the canvas upward (which would overdraw the row beneath
+ // on the PDF backend) — instead the canvas itself is bled to the page
+ // edges via negative margins.
+ DocumentNode band = new ShapeBuilder()
+ .name("CvV2MintEditorialHeaderBand")
+ .size(pageWidth, bandHeight)
+ .fillColor(headerBandColor)
+ .build();
+ DocumentNode rule = new ShapeBuilder()
+ .name("CvV2MintEditorialHeaderRule")
+ .size(pageWidth, ruleThickness)
+ .fillColor(ruleColor)
+ .build();
+ ParagraphNode name = new ParagraphBuilder()
+ .name("CvV2MintEditorialHeaderName")
+ .text(TextOrnaments.spacedUpper(identity.name().full()))
+ .textStyle(mastheadNameStyle())
+ .align(TextAlign.CENTER)
+ .build();
+ String jobTitle = identity.jobTitle();
+ boolean hasTagline = jobTitle != null && !jobTitle.isBlank();
+ ParagraphNode tagline = hasTagline
+ ? new ParagraphBuilder()
+ .name("CvV2MintEditorialHeaderTagline")
+ .text(TextOrnaments.spacedUpper(jobTitle))
+ .textStyle(taglineStyle())
+ .align(TextAlign.CENTER)
+ .build()
+ : null;
+
+ section.addCanvas(pageWidth, canvasH, canvas -> {
+ canvas.name("CvV2MintEditorialHeaderCanvas")
+ .clipPolicy(ClipPolicy.OVERFLOW_VISIBLE)
+ // Bleed the whole canvas to the top + side page edges so
+ // the band reaches y=0 and both side edges.
+ .margin(new DocumentInsets(-ruleBleed, -ruleBleed, 0,
+ -ruleBleed))
+ // Band fills the masthead zone from the page top edge to
+ // the rule's bottom; rule + name + tagline sit at their
+ // default flow positions on top.
+ .position(band, 0.0, 0.0)
+ .position(rule, 0.0, MASTHEAD_RULE_Y)
+ .position(name, 0.0, MASTHEAD_NAME_Y);
+ if (tagline != null) {
+ canvas.position(tagline, 0.0, MASTHEAD_TAGLINE_Y);
+ }
+ });
+ }
+
// -- Sidebar: Contact ---------------------------------------------
private void addContact(SectionBuilder section, CvIdentity identity) {
@@ -513,6 +761,23 @@ private void addProfile(SectionBuilder section, CvSection profile) {
// -- Main: Experience ---------------------------------------------
+ /**
+ * Renders the Experience block with Mint's bespoke entry layout:
+ * a spaced-caps job title, a single {@code subtitle | date} meta line,
+ * a prose paragraph, and — uniquely for this preset — any trailing
+ * markdown bullet lines as a real bullet list.
+ *
+ * This is rendered locally rather than through the shared
+ * {@code EntryCompactRenderer} / {@code RichParagraphRenderer} because
+ * Mint's entry shape does not match those renderers: the title is
+ * transformed to letter-spaced uppercase, the subtitle and date are
+ * fused into one {@code "Company | Location | 2010 - Present"} meta line
+ * (the shared renderers keep them as separate title-row columns), and
+ * the body is split into prose + highlight bullets via
+ * {@link #splitBody(String)} — a transform no shared renderer performs.
+ * Bodies with no bullet lines (the canonical sample) take the plain
+ * single-paragraph path and are unaffected.
+ */
private void addExperience(SectionBuilder section, String title,
List entries) {
if (entries.isEmpty()) {
@@ -750,6 +1015,18 @@ private DocumentTableCell gridCell(String text, DocumentTableStyle style) {
// -- Style factories ----------------------------------------------
+ /**
+ * Masthead name style. With the default {@code nameColor} (ink) this is
+ * identical to {@code theme.headlineStyle()} — headline font, headline
+ * size, default decoration — so the stock render is unchanged; only the
+ * colour differs when a caller overrides {@code nameColor}.
+ */
+ private DocumentTextStyle mastheadNameStyle() {
+ return CvTextStyles.of(theme.typography().headlineFont(),
+ theme.typography().sizeHeadline(),
+ DocumentTextDecoration.DEFAULT, nameColor);
+ }
+
private DocumentTextStyle taglineStyle() {
return CvTextStyles.of(theme.typography().headlineFont(),
theme.typography().sizeContact(),
@@ -837,6 +1114,12 @@ private static List entriesOf(CvSection section) {
* {@code "* "}). Bodies with no bullet lines yield the whole text as
* prose and an empty bullet list, so the canonical sample renders
* exactly as before.
+ *
+ * Preset-local because the shared CV body renderers
+ * ({@code RichParagraphRenderer}, {@code EntryCompactRenderer}) treat the
+ * entry body as one rich paragraph and never break trailing bullet lines
+ * out into a list. This split is what lets a Mint experience entry show a
+ * paragraph followed by highlight bullets (see {@link Template#addExperience}).
*/
private static BodyParts splitBody(String body) {
if (body == null || body.isBlank()) {
diff --git a/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorialSmokeTest.java b/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorialSmokeTest.java
index ffa43d51..3901fcf1 100644
--- a/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorialSmokeTest.java
+++ b/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/MintEditorialSmokeTest.java
@@ -4,6 +4,7 @@
import com.demcha.compose.document.api.DocumentPageSize;
import com.demcha.compose.document.api.DocumentSession;
import com.demcha.compose.document.layout.LayoutGraph;
+import com.demcha.compose.document.layout.PlacedFragment;
import com.demcha.compose.document.templates.api.DocumentTemplate;
import com.demcha.compose.document.templates.cv.v2.data.CvDocument;
import com.demcha.compose.document.templates.cv.v2.data.CvIdentity;
@@ -14,11 +15,13 @@
import com.demcha.compose.document.templates.cv.v2.data.RowsSection;
import com.demcha.compose.document.templates.cv.v2.data.SkillsSection;
import com.demcha.compose.document.templates.cv.v2.theme.CvTheme;
+import com.demcha.compose.document.style.DocumentColor;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.within;
/**
* Smoke test for the v2 Mint Editorial preset. Covers stable identity,
@@ -64,6 +67,101 @@ void custom_theme_factory_renders() throws Exception {
}
}
+ @Test
+ void custom_colour_options_render_two_pages() throws Exception {
+ // Dark header band + white name + a contrasting rule and accent —
+ // exercises every Options knob at once. Still a clean two-page render.
+ MintEditorial.Options options = MintEditorial.Options.builder()
+ .headerBandColor(DocumentColor.rgb(24, 24, 24))
+ .nameColor(DocumentColor.WHITE)
+ .ruleColor(DocumentColor.rgb(220, 120, 90))
+ .accentColor(DocumentColor.rgb(139, 207, 190))
+ .build();
+ try (DocumentSession session = GraphCompose.document()
+ .pageSize(DocumentPageSize.A4)
+ .margin(48, 48, 48, 48)
+ .create()) {
+ MintEditorial.create(options).compose(session, fullDocument());
+ assertThat(session.roots()).isNotEmpty();
+ assertThat(session.layoutGraph().totalPages()).isEqualTo(2);
+ }
+ }
+
+ @Test
+ void default_options_equal_no_options() {
+ // The default Options factory must leave the stock surface identity
+ // intact (and, by the parity gate, the stock render).
+ DocumentTemplate withDefaults =
+ MintEditorial.create(MintEditorial.Options.defaults());
+ assertThat(withDefaults.id()).isEqualTo("mint-editorial");
+ assertThat(withDefaults.displayName()).isEqualTo("Mint Editorial");
+ }
+
+ @Test
+ void band_constants_match_default_masthead() throws Exception {
+ // Guard: the banded masthead reuses hand-measured MASTHEAD_* constants
+ // to place the name/tagline/rule at the SAME positions the default
+ // (bandless) flow produces. This test ties MASTHEAD_RULE_Y to the real
+ // default rule y, so any future typography / margin / spacing change
+ // that moves the masthead fails here and signals the constants must be
+ // re-measured.
+ try (DocumentSession session = GraphCompose.document()
+ .pageSize(DocumentPageSize.A4)
+ .margin(48, 48, 48, 48)
+ .create()) {
+ MintEditorial.create().compose(session, fullDocument());
+ LayoutGraph layout = session.layoutGraph();
+ PlacedFragment rule = layout.fragments().stream()
+ .filter(f -> f.pageIndex() == 0)
+ .filter(f -> f.path().contains("CvV2MintEditorialHeaderRule"))
+ .findFirst()
+ .orElseThrow(() -> new AssertionError(
+ "default masthead rule fragment not found"));
+ // PlacedFragment.y is the PDF bottom-left origin (y grows up);
+ // convert to the top-down page-edge coordinate the constant uses.
+ double pageHeight = session.canvas().height();
+ double ruleTop = pageHeight - (rule.y() + rule.height());
+ assertThat(ruleTop)
+ .as("default rule top must equal MASTHEAD_RULE_Y (re-measure "
+ + "the MASTHEAD_* band constants if this drifts)")
+ .isCloseTo(MintEditorial.MASTHEAD_RULE_Y, within(0.5));
+ }
+ }
+
+ @Test
+ void banded_and_bandless_place_first_row_identically() throws Exception {
+ // Complementary guard: the band must not shift the body. The first
+ // page-1 content row must start at the same y with and without a band.
+ double bandless = firstPageOneRowTop(MintEditorial.create());
+ double banded = firstPageOneRowTop(MintEditorial.create(
+ MintEditorial.Options.builder()
+ .headerBandColor(DocumentColor.rgb(228, 217, 198))
+ .build()));
+ assertThat(banded)
+ .as("banded masthead must place the first row at the same y as "
+ + "the bandless masthead")
+ .isCloseTo(bandless, within(0.5));
+ }
+
+ private static double firstPageOneRowTop(DocumentTemplate template)
+ throws Exception {
+ try (DocumentSession session = GraphCompose.document()
+ .pageSize(DocumentPageSize.A4)
+ .margin(48, 48, 48, 48)
+ .create()) {
+ template.compose(session, fullDocument());
+ LayoutGraph layout = session.layoutGraph();
+ double pageHeight = session.canvas().height();
+ return layout.fragments().stream()
+ .filter(f -> f.pageIndex() == 0)
+ .filter(f -> f.path().contains("CvV2MintEditorialPageOne"))
+ .mapToDouble(f -> pageHeight - (f.y() + f.height()))
+ .min()
+ .orElseThrow(() -> new AssertionError(
+ "page-1 row fragments not found"));
+ }
+ }
+
@Test
void renders_with_awards_and_references_grids() throws Exception {
try (DocumentSession session = GraphCompose.document()
From 570fa91b623c4ea983830396d511e0aec6e86377 Mon Sep 17 00:00:00 2001
From: DemchaAV
Date: Sat, 30 May 2026 03:20:53 +0100
Subject: [PATCH 2/2] 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.
---
CHANGELOG.md | 18 ++++++++++++++++++
.../templates/v2-layered/authoring-presets.md | 18 ++++++++++++++++++
.../CoverLetterV2VisualParityTest.java | 5 ++++-
.../cv/v2/presets/CvV2VisualParityTest.java | 5 ++++-
.../mint-editorial-letter-page-0.png | Bin 0 -> 28794 bytes
.../cv-v2-layered/mint_editorial-page-0.png | Bin 0 -> 57606 bytes
.../cv-v2-layered/mint_editorial-page-1.png | Bin 0 -> 26101 bytes
7 files changed, 44 insertions(+), 2 deletions(-)
create mode 100644 src/test/resources/visual-baselines/coverletter-v2-layered/mint-editorial-letter-page-0.png
create mode 100644 src/test/resources/visual-baselines/cv-v2-layered/mint_editorial-page-0.png
create mode 100644 src/test/resources/visual-baselines/cv-v2-layered/mint_editorial-page-1.png
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5f1b14c..d9d4c4bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,24 @@ follow semantic versioning; release dates are ISO 8601.
template surface, including its isolated theme tokens, visual
regression baselines, and reusable `Subheadline` /
`SectionHeader.flatSpacedCaps` widget support.
+- Added the **Mint Editorial** template set: a two-page, two-column
+ editorial CV preset `MintEditorial` (centred spaced-caps masthead with
+ a full-width mint accent rule; sidebar contact / interests / education /
+ expertise / skill-bars / social beside a profile / experience / awards /
+ references main column) and its paired `MintEditorialLetter`, both on
+ `CvTheme.mintEditorial()` and with visual regression baselines.
+- Added two reusable `cv/v2/widgets`: `SkillBar` (data-driven proficiency
+ bar — spaced-caps label above a track with a level-positioned marker;
+ no bar when the level is absent) and `IconTextRow` (inline icon + text
+ row, optionally a single click target), with `WidgetSmokeTest` coverage.
+- Added optional proficiency levels to `SkillGroup` via the new
+ `CvSkill` record and `SkillsSection.Builder.leveledGroup(...)`. Fully
+ backward-compatible: name-only skills carry no level and every existing
+ name-based renderer is unaffected.
+- Added `MintEditorial.Options` (and a matching `MintEditorialLetter.Options`)
+ — an additive masthead colour API (accent, rule, name, and an optional
+ full-width page-1 header band) whose defaults reproduce the stock render
+ exactly, so the committed look and the parity baselines are unchanged.
### Public API
diff --git a/docs/templates/v2-layered/authoring-presets.md b/docs/templates/v2-layered/authoring-presets.md
index b932bda4..dd73154c 100644
--- a/docs/templates/v2-layered/authoring-presets.md
+++ b/docs/templates/v2-layered/authoring-presets.md
@@ -107,6 +107,24 @@ in `com.demcha.compose.document.templates.widgets`.
| `SectionHeader.upperRule(host, title, theme, titleStyle, ruleColor, ruleWidth)` | Uppercase label with short rule below |
| `SectionHeader.spacedCapsRule(host, title, theme, titleStyle, ruleColor, ruleWidth, ruleThickness, ruleMargin)` | Spaced-caps label with short rule below |
+### `SkillBar` — data-driven proficiency bar
+
+| Variant | Visual |
+|---|---|
+| `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 |
+
+Reads the level from `CvSkill.level()` (`[0, 1]`); used by the Mint
+Editorial skills sidebar.
+
+### `IconTextRow` — inline icon + text row
+
+| Variant | Visual |
+|---|---|
+| `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 |
+
+Used for the icon-led contact and social rows in sidebar CV layouts
+(Mint Editorial).
+
### Higher-order CV widgets
| Widget | Visual |
diff --git a/src/test/java/com/demcha/compose/document/templates/coverletter/v2/presets/CoverLetterV2VisualParityTest.java b/src/test/java/com/demcha/compose/document/templates/coverletter/v2/presets/CoverLetterV2VisualParityTest.java
index bb796752..c61ba18c 100644
--- a/src/test/java/com/demcha/compose/document/templates/coverletter/v2/presets/CoverLetterV2VisualParityTest.java
+++ b/src/test/java/com/demcha/compose/document/templates/coverletter/v2/presets/CoverLetterV2VisualParityTest.java
@@ -114,7 +114,10 @@ private static Stream presets() {
(Supplier>) MonogramSidebarLetter::create),
Arguments.of("timeline_minimal",
TimelineMinimalLetter.RECOMMENDED_MARGIN,
- (Supplier>) TimelineMinimalLetter::create));
+ (Supplier>) TimelineMinimalLetter::create),
+ Arguments.of("mint-editorial-letter",
+ MintEditorialLetter.RECOMMENDED_MARGIN,
+ (Supplier>) MintEditorialLetter::create));
}
/**
diff --git a/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/CvV2VisualParityTest.java b/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/CvV2VisualParityTest.java
index addd9e78..0b6220be 100644
--- a/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/CvV2VisualParityTest.java
+++ b/src/test/java/com/demcha/compose/document/templates/cv/v2/presets/CvV2VisualParityTest.java
@@ -131,7 +131,10 @@ private static Stream presets() {
(Supplier>) MonogramSidebar::create),
Arguments.of("sidebar_portrait",
SidebarPortrait.RECOMMENDED_MARGIN,
- (Supplier>) SidebarPortrait::create));
+ (Supplier>) SidebarPortrait::create),
+ Arguments.of("mint_editorial",
+ MintEditorial.RECOMMENDED_MARGIN,
+ (Supplier>) MintEditorial::create));
}
/**
diff --git a/src/test/resources/visual-baselines/coverletter-v2-layered/mint-editorial-letter-page-0.png b/src/test/resources/visual-baselines/coverletter-v2-layered/mint-editorial-letter-page-0.png
new file mode 100644
index 0000000000000000000000000000000000000000..58d297b65cce7d286b54ff79df0a15373e6671bd
GIT binary patch
literal 28794
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