From e27fb02c15f1809590a5115e98e6fe1347e1094d Mon Sep 17 00:00:00 2001
From: DemchaAV
Date: Tue, 30 Jun 2026 22:57:18 +0100
Subject: [PATCH] refactor(templates): remove the classic cover-letter family
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Gen-2 cover-letter stack (coverletter.{presets,builder,spec,layouts} +
data.coverletter) is superseded by the layered coverletter.v2 surface. It is
removed before the classic CV family because each classic cover-letter preset
cross-references its paired cv.presets preset in Javadoc, which the javadoc
gate would reject once cv.presets is gone; CV does not reference cover-letter.
Delete the classic cover-letter packages, their tests, and the CoverLetterMock
fixture; repoint the cover-letter package-info at the v2 stack. Strip the
classic cover-letter helpers from TemplateTestSupport and ExampleDataFactory
(the v2 sample and sampleHeader stay) and the data.coverletter entry from the
data package-info. Also drop an orphaned classic cover-letter layout snapshot
that no test loads.
Tests: ./mvnw verify javadoc:javadoc -pl . — 1553 tests, 0 failures, javadoc
clean; examples + benchmarks compile; examples-generation smoke (85) green,
including the v2 cover-letter gallery.
---
.../examples/support/ExampleDataFactory.java | 28 --
.../builder/CoverLetterBuilder.java | 260 ------------------
.../coverletter/builder/package-info.java | 14 -
.../coverletter/layouts/LetterFormat.java | 93 -------
.../coverletter/layouts/package-info.java | 23 --
.../templates/coverletter/package-info.java | 43 +--
.../coverletter/presets/BlueBannerLetter.java | 85 ------
.../presets/BoxedSectionsLetter.java | 83 ------
.../presets/CenteredHeadlineLetter.java | 84 ------
.../presets/ClassicSerifLetter.java | 83 ------
.../presets/CompactMonoLetter.java | 84 ------
.../presets/EditorialBlueLetter.java | 84 ------
.../presets/EngineeringResumeLetter.java | 84 ------
.../coverletter/presets/ExecutiveLetter.java | 83 ------
.../presets/ModernProfessionalLetter.java | 98 -------
.../presets/MonogramSidebarLetter.java | 86 ------
.../presets/NordicCleanLetter.java | 87 ------
.../coverletter/presets/PanelLetter.java | 83 ------
.../presets/SidebarPortraitLetter.java | 86 ------
.../presets/TimelineMinimalLetter.java | 83 ------
.../coverletter/presets/package-info.java | 24 --
.../coverletter/spec/CoverLetterHeader.java | 180 ------------
.../coverletter/spec/CoverLetterSpec.java | 131 ---------
.../coverletter/spec/package-info.java | 32 ---
.../coverletter/CoverLetterDocumentSpec.java | 150 ----------
.../data/coverletter/JobDetails.java | 149 ----------
.../data/coverletter/package-info.java | 4 -
.../document/templates/data/package-info.java | 6 +-
.../templates/TemplateTestSupport.java | 18 --
.../presets/CoverLetterGalleryTest.java | 158 -----------
.../presets/CoverLetterPilotTest.java | 113 --------
.../presets/PresetLayoutSnapshotTest.java | 94 -------
.../presets/PresetVisualParityTest.java | 126 ---------
.../CoverLetterDocumentSpecTest.java | 40 ---
.../coverletter/JobDetailsBuilderTest.java | 29 --
.../java/com/demcha/mock/CoverLetterMock.java | 19 --
.../cover-letter/cover_letter_standard.json | 257 -----------------
37 files changed, 11 insertions(+), 3173 deletions(-)
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/layouts/LetterFormat.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/BlueBannerLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/CenteredHeadlineLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/PanelLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterHeader.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpec.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java
delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterGalleryTest.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterPilotTest.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetLayoutSnapshotTest.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpecTest.java
delete mode 100644 src/test/java/com/demcha/compose/document/templates/data/coverletter/JobDetailsBuilderTest.java
delete mode 100644 src/test/java/com/demcha/mock/CoverLetterMock.java
delete mode 100644 src/test/resources/layout-snapshots/canonical-templates/cover-letter/cover_letter_standard.json
diff --git a/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java b/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java
index 8d1581dca..e1fc61a1e 100644
--- a/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java
+++ b/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java
@@ -11,7 +11,6 @@
import com.demcha.compose.document.templates.cv.v2.data.SkillsSection;
import com.demcha.compose.document.templates.data.common.EmailYaml;
import com.demcha.compose.document.templates.data.common.Header;
-import com.demcha.compose.document.templates.data.coverletter.CoverLetterDocumentSpec;
import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec;
import com.demcha.compose.document.templates.data.cv.CvDocumentSpec;
import com.demcha.compose.document.templates.data.proposal.ProposalDocumentSpec;
@@ -65,33 +64,6 @@ public static Header sampleHeader() {
.build();
}
- public static String sampleCoverLetter() {
- return """
- Hiring team at ${companyName},
-
- I am excited to share my interest in the Senior Platform Engineer role. My recent work has focused on building reusable document-generation systems that balance public API design, render quality, and maintainability.
-
- I enjoy translating fuzzy workflow requirements into clear template abstractions, reliable test coverage, and examples that make adoption easier for the rest of the team.
-
- I would welcome the opportunity to bring that same mix of engineering rigor and product thinking to your platform group.
- """;
- }
-
- public static CoverLetterDocumentSpec sampleCoverLetterDocument() {
- return CoverLetterDocumentSpec.builder()
- .header(sampleHeader())
- .letter(sampleCoverLetter())
- .job(job -> job
- .url("https://northwind.example/jobs/platform")
- .title("Senior Platform Engineer")
- .company("Northwind Systems")
- .location("London / Remote")
- .description("Lead reusable internal platform capabilities.")
- .seniorityLevel("Senior")
- .employmentType("Full-time"))
- .build();
- }
-
public static InvoiceDocumentSpec sampleInvoice() {
return InvoiceDocumentSpec.builder()
.title("Invoice")
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java b/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java
deleted file mode 100644
index 6b976eece..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.builder;
-
-import com.demcha.compose.document.api.DocumentSession;
-import com.demcha.compose.document.node.ContainerNode;
-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.DocumentInsets;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.core.text.MarkdownText;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * Fluent builder for assembling a Templates v2 cover-letter
- * {@link DocumentTemplate}.
- *
- *
A cover-letter preset wraps one builder call inside its
- * {@code create(BusinessTheme)} factory — the same flat-recipe
- * pattern used by CV presets. Each preset shares the typography
- * palette of its paired CV preset (same heading style, same body
- * style, same spacing rhythm) so a writer's CV and cover letter
- * read as one matched set.
- *
- *
All seven knobs ({@code id}, {@code displayName},
- * {@code header}, {@code layout}, {@code bodyStyle}, {@code spacing},
- * and at least implicit alignment via the layout / body style) must
- * be configured before calling {@link #build()}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard) — the layered model
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}
- * plus the {@code coverletter.v2} presets. Kept for backward
- * compatibility; scheduled for removal in a future major. See
- * {@code docs/templates/v2-layered/}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class CoverLetterBuilder {
-
- private String id;
- private String displayName;
- private Header header;
- private LetterFormat layout;
- private DocumentTextStyle bodyStyle;
- private Spacing spacing;
-
- private CoverLetterBuilder() {
- }
-
- /**
- * Returns a fresh builder.
- *
- * @return new builder instance
- */
- public static CoverLetterBuilder builder() {
- return new CoverLetterBuilder();
- }
-
- /**
- * Sets the stable identifier exposed via
- * {@link DocumentTemplate#id()}.
- *
- * @param value non-null identifier
- * @return this builder
- */
- public CoverLetterBuilder id(String value) {
- this.id = Objects.requireNonNull(value, "id");
- return this;
- }
-
- /**
- * Sets the human-readable display name.
- *
- * @param value non-null display name
- * @return this builder
- */
- public CoverLetterBuilder displayName(String value) {
- this.displayName = Objects.requireNonNull(value, "displayName");
- return this;
- }
-
- /**
- * Sets the header component used to render the document header.
- *
- * @param value non-null header component
- * @return this builder
- */
- public CoverLetterBuilder header(Header value) {
- this.header = Objects.requireNonNull(value, "header");
- return this;
- }
-
- /**
- * Sets the layout responsible for arranging header + letter
- * blocks.
- *
- * @param value non-null layout
- * @return this builder
- */
- public CoverLetterBuilder layout(LetterFormat value) {
- this.layout = Objects.requireNonNull(value, "layout");
- return this;
- }
-
- /**
- * Sets the text style applied to greeting, body paragraphs, and
- * closing.
- *
- * @param value non-null body text style
- * @return this builder
- */
- public CoverLetterBuilder bodyStyle(DocumentTextStyle value) {
- this.bodyStyle = Objects.requireNonNull(value, "bodyStyle");
- return this;
- }
-
- /**
- * Sets the active spacing tokens.
- *
- * @param value non-null spacing tokens
- * @return this builder
- */
- public CoverLetterBuilder spacing(Spacing value) {
- this.spacing = Objects.requireNonNull(value, "spacing");
- return this;
- }
-
- /**
- * Validates configuration and returns the assembled
- * {@link DocumentTemplate}.
- *
- * @return ready-to-use template instance
- * @throws NullPointerException if any required setter has not been
- * called
- */
- public DocumentTemplate build() {
- Objects.requireNonNull(id, "id");
- Objects.requireNonNull(displayName, "displayName");
- Objects.requireNonNull(header, "header");
- Objects.requireNonNull(layout, "layout");
- Objects.requireNonNull(bodyStyle, "bodyStyle");
- Objects.requireNonNull(spacing, "spacing");
-
- final String capturedId = id;
- final String capturedDisplay = displayName;
- final Header capturedHeader = header;
- final LetterFormat capturedLayout = layout;
- final DocumentTextStyle capturedBody = bodyStyle;
- final Spacing capturedSpacing = spacing;
-
- return new DocumentTemplate() {
- @Override
- public String id() {
- return capturedId;
- }
-
- @Override
- public String displayName() {
- return capturedDisplay;
- }
-
- @Override
- public void compose(DocumentSession session, CoverLetterSpec spec) {
- Objects.requireNonNull(session, "session");
- Objects.requireNonNull(spec, "spec");
-
- DocumentNode headerNode = composeHeader(spec);
- List blocks = new ArrayList<>(3);
- if (!spec.greeting().isBlank()) {
- blocks.add(paragraph(
- "letter.greeting",
- spec.greeting(),
- /* topMargin */ capturedSpacing.moduleGap(),
- /* bottomMargin */ capturedSpacing.paragraphSpacing()));
- }
- blocks.add(bodyContainer(spec.bodyParagraphs()));
- if (!spec.closing().isBlank()) {
- blocks.add(paragraph(
- "letter.closing",
- spec.closing(),
- /* topMargin */ capturedSpacing.paragraphSpacing(),
- /* bottomMargin */ 0.0));
- }
-
- DocumentNode root = capturedLayout.compose(headerNode, blocks);
- session.add(root);
- }
-
- private DocumentNode composeHeader(CoverLetterSpec spec) {
- Header.Input input = new Header.Input(
- spec.header().name(),
- spec.header().contactItems(),
- headerLinks(spec.header()));
- return capturedHeader.compose(input);
- }
-
- private List headerLinks(CoverLetterHeader header) {
- List result = new ArrayList<>();
- if (!header.email().isBlank()) {
- result.add(Header.Link.active(
- header.email(),
- "mailto:" + header.email()));
- }
- for (CoverLetterHeader.Link link : header.links()) {
- if (link.url().isBlank()) {
- result.add(Header.Link.plain(link.label()));
- } else {
- result.add(Header.Link.active(link.label(), link.url()));
- }
- }
- return result;
- }
-
- private DocumentNode bodyContainer(List paragraphs) {
- List children = new ArrayList<>(paragraphs.size());
- for (int i = 0; i < paragraphs.size(); i++) {
- children.add(paragraph(
- "letter.body[" + i + "]",
- paragraphs.get(i),
- /* topMargin */ 0.0,
- /* bottomMargin */ 0.0));
- }
- return new ContainerNode(
- "letter.body",
- children,
- /* spacing */ capturedSpacing.paragraphSpacing(),
- DocumentInsets.zero(),
- DocumentInsets.zero(),
- null, null, null, null);
- }
-
- private ParagraphNode paragraph(String name, String text,
- double topMargin, double bottomMargin) {
- return new ParagraphNode(
- name,
- /* text */ "",
- /* inlineRuns */ MarkdownText.parse(text, capturedBody),
- capturedBody,
- TextAlign.LEFT,
- capturedSpacing.lineSpacing(),
- /* bulletOffset */ "",
- /* indentStrategy */ null,
- /* link */ null,
- /* bookmark */ null,
- /* padding */ DocumentInsets.zero(),
- /* margin */ new DocumentInsets(
- topMargin, 0.0, bottomMargin, 0.0),
- /* autoSize */ null);
- }
- };
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java
deleted file mode 100644
index 6d8c55f67..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Templates v2 cover-letter preset builder — fluent assembly of
- * {@link com.demcha.compose.document.templates.api.DocumentTemplate}
- * instances for cover letters.
- *
- *
The single class of interest is
- * {@link com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder}.
- * Preset classes wrap one builder call inside their
- * {@code create(BusinessTheme)} factory; users wanting a custom
- * cover-letter preset copy that factory body and tweak the chain.
Single-column layout with generous paragraph spacing — header
- * sits at the top, then greeting, body paragraphs, and closing
- * stack vertically beneath it. There is no slot map: a cover
- * letter is structurally simpler than a CV (one continuous reading
- * flow), so the layout takes the rendered nodes in source order and
- * emits one container.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard) — the layered model
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}
- * plus the {@code coverletter.v2} presets. Kept for backward
- * compatibility; scheduled for removal in a future major. See
- * {@code docs/templates/v2-layered/}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class LetterFormat {
-
- private static final String LAYOUT_NAME = "layout.letterFormat";
-
- private double moduleGap = 0.0;
-
- private LetterFormat() {
- }
-
- /**
- * Returns a fresh layout with zero gap (caller drives spacing
- * through node margins).
- *
- * @return new layout instance
- */
- public static LetterFormat layout() {
- return new LetterFormat();
- }
-
- /**
- * Sets the vertical gap between top-level letter blocks (header,
- * greeting, body, closing).
- *
- * @param value non-negative finite gap in points
- * @return this layout (for chaining)
- * @throws IllegalArgumentException if {@code value} is negative,
- * {@code NaN}, or infinite
- */
- public LetterFormat moduleGap(double value) {
- if (Double.isNaN(value) || Double.isInfinite(value) || value < 0) {
- throw new IllegalArgumentException("moduleGap must be finite and non-negative: " + value);
- }
- this.moduleGap = value;
- return this;
- }
-
- /**
- * Composes the final {@link DocumentNode} from a header plus
- * ordered list of letter blocks (greeting, body, closing).
- *
- * @param header non-null header node
- * @param blocks non-null ordered list of letter blocks
- * @return container node holding the header and blocks in order
- * @throws NullPointerException if either argument is null
- */
- public DocumentNode compose(DocumentNode header, List blocks) {
- Objects.requireNonNull(header, "header");
- Objects.requireNonNull(blocks, "blocks");
-
- List children = new ArrayList<>(blocks.size() + 1);
- children.add(header);
- children.addAll(blocks);
-
- return new ContainerNode(
- LAYOUT_NAME,
- children,
- moduleGap,
- DocumentInsets.zero(),
- DocumentInsets.zero(),
- /* fillColor */ null,
- /* stroke */ null,
- /* cornerRadius */ null,
- /* borders */ null);
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java
deleted file mode 100644
index 085dabf0c..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Superseded Gen-2 cover-letter layouts — frames that arrange a header
- * plus letter blocks (greeting, body paragraphs, closing) into a
- * final document tree.
- *
- *
Deprecated surface. These are the older Gen-2
- * cover-letter layouts. They are not the current standard. The
- * current standard is the layered surface
- * {@code com.demcha.compose.document.templates.coverletter.v2} (data / theme /
- * components / widgets / presets). This package is kept only for backward
- * compatibility and is scheduled for removal in a future major.
- *
- *
Currently a single layout
- * ({@link com.demcha.compose.document.templates.coverletter.layouts.LetterFormat})
- * covers all 14 cover-letter pair presets.
- *
- *
New code should target the layered {@code coverletter.v2} surface
- * instead. See {@code docs/templates/v2-layered/}.
Deprecated surface. This package is the older Gen-2
- * cover-letter template stack. It is not the current standard. The
- * current standard is the layered surface
- * {@code com.demcha.compose.document.templates.coverletter.v2} (data / theme /
- * components / widgets / presets). This package is kept only for backward
- * compatibility and is scheduled for removal in a future major.
+ *
The shipping cover-letter surface is the layered stack under
+ * {@code coverletter.v2} (data / theme / components / widgets / presets),
+ * built on the shared {@code templates.core} layer and a {@code BrandTheme}.
*
- *
Sub-packages partition the (deprecated) domain by concern:
- *
- *
- *
{@code coverletter.layouts} — slot frames (LetterFormat — a
- * single-column layout with generous side margins for letter body
- * text).
{@code coverletter.builder} — {@code CoverLetterBuilder} for
- * users composing their own preset.
- *
{@code coverletter.spec} — data records ({@code CoverLetterSpec}
- * with header, greeting, body paragraphs, closing).
- *
- *
- *
New code should target the layered {@code coverletter.v2} surface
- * instead. See {@code docs/templates/v2-layered/}.
- *
- *
Naming note: the user-facing concept is
- * "cover-letter" with a hyphen, but Java packages cannot contain hyphens.
- * The package name {@code coverletter} drops the hyphen for compatibility;
- * file id strings and example file names retain the hyphenated form
- * (e.g. {@code cover-letter-modern-professional.pdf}).
+ *
Naming note: the user-facing concept is "cover-letter"
+ * with a hyphen, but Java packages cannot contain hyphens. The package name
+ * {@code coverletter} drops the hyphen; file id strings and example file names
+ * retain the hyphenated form (e.g. {@code cover-letter-modern-professional.pdf}).
PT Serif headline + Lato body, dark INK with the soft-blue
- * BANNER_BG used by
- * {@link com.demcha.compose.document.templates.cv.presets.BlueBanner}
- * for accent runs.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.BlueBannerLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class BlueBannerLetter {
-
- /** Stable template identifier. */
- public static final String ID = "blue-banner-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Blue Banner Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(20, 25, 35);
- private static final DocumentColor SOFT = DocumentColor.rgb(85, 85, 85);
- private static final DocumentColor BANNER_BG = DocumentColor.rgb(112, 146, 190);
-
- private BlueBannerLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code BlueBanner} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Blue Banner Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.PT_SERIF)
- .size(22.0)
- .decoration(DocumentTextDecoration.DEFAULT)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(7.5)
- .color(SOFT)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(BANNER_BG)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java
deleted file mode 100644
index 0c78c1247..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code BoxedSections} CV preset.
- *
- *
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.CenteredHeadlineLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class CenteredHeadlineLetter {
-
- /** Stable template identifier. */
- public static final String ID = "centered-headline-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Centered Headline Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(54, 54, 54);
- private static final DocumentColor HEADLINE = DocumentColor.rgb(70, 70, 70);
- private static final DocumentColor SOFT = DocumentColor.rgb(105, 105, 105);
- private static final DocumentColor RULE = DocumentColor.rgb(188, 188, 188);
-
- private CenteredHeadlineLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code CenteredHeadline} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Centered Headline Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.POPPINS)
- .size(24.0)
- .decoration(DocumentTextDecoration.DEFAULT)
- .color(HEADLINE)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.3)
- .color(SOFT)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.3)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(SOFT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java
deleted file mode 100644
index 452f89e8a..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code ClassicSerif} CV preset.
- *
- *
PT Serif throughout with the bronze accent and warm INK palette
- * of {@link com.demcha.compose.document.templates.cv.presets.ClassicSerif}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ClassicSerifLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class ClassicSerifLetter {
-
- /** Stable template identifier. */
- public static final String ID = "classic-serif-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Classic Serif Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(45, 43, 40);
- private static final DocumentColor MUTED = DocumentColor.rgb(105, 101, 94);
- private static final DocumentColor ACCENT = DocumentColor.rgb(126, 93, 52);
-
- private ClassicSerifLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code ClassicSerif} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Classic Serif Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.PT_SERIF)
- .size(24.0)
- .decoration(DocumentTextDecoration.DEFAULT)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.PT_SERIF)
- .size(8.7)
- .color(MUTED)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.PT_SERIF)
- .size(8.7)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.PT_SERIF)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java
deleted file mode 100644
index 1e3224eaa..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code CompactMono} CV preset.
- *
- *
IBM Plex Mono headline + Lato body, dark INK ink with the
- * teal-blue ACCENT used by
- * {@link com.demcha.compose.document.templates.cv.presets.CompactMono}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.CompactMonoLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class CompactMonoLetter {
-
- /** Stable template identifier. */
- public static final String ID = "compact-mono-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Compact Mono Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(28, 34, 42);
- private static final DocumentColor MUTED = DocumentColor.rgb(84, 96, 112);
- private static final DocumentColor ACCENT = DocumentColor.rgb(0, 126, 151);
-
- private CompactMonoLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code CompactMono} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Compact Mono Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.compact();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.IBM_PLEX_MONO)
- .size(20.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.5)
- .color(MUTED)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java
deleted file mode 100644
index 72898fead..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code EditorialBlue} CV preset.
- *
- *
Helvetica throughout, deep navy ink with bright editorial blue
- * accent — matches
- * {@link com.demcha.compose.document.templates.cv.presets.EditorialBlue}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.EditorialBlueLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class EditorialBlueLetter {
-
- /** Stable template identifier. */
- public static final String ID = "editorial-blue-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Editorial Blue Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(18, 31, 72);
- private static final DocumentColor BODY = DocumentColor.rgb(60, 72, 106);
- private static final DocumentColor ACCENT = DocumentColor.rgb(86, 136, 255);
-
- private EditorialBlueLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code EditorialBlue} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Editorial Blue Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA_BOLD)
- .size(22.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(9.0)
- .color(BODY)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(9.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(10.0)
- .color(BODY)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java
deleted file mode 100644
index 105985f8c..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code EngineeringResume} CV preset.
- *
- *
Navy primary, green accent, Barlow headline + Lato body — matches
- * {@link com.demcha.compose.document.templates.cv.presets.EngineeringResume}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.EngineeringResumeLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class EngineeringResumeLetter {
-
- /** Stable template identifier. */
- public static final String ID = "engineering-resume-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Engineering Resume Letter";
-
- private static final DocumentColor NAVY = DocumentColor.rgb(13, 32, 47);
- private static final DocumentColor INK = DocumentColor.rgb(32, 42, 55);
- private static final DocumentColor MUTED = DocumentColor.rgb(91, 105, 119);
- private static final DocumentColor GREEN = DocumentColor.rgb(27, 145, 104);
-
- private EngineeringResumeLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code EngineeringResume} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Engineering Resume Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.compact();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.BARLOW)
- .size(24.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(NAVY)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.5)
- .color(MUTED)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(GREEN)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java
deleted file mode 100644
index 76a1ba803..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code Executive} CV preset.
- *
- *
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ExecutiveLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class ExecutiveLetter {
-
- /** Stable template identifier. */
- public static final String ID = "executive-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Executive Letter";
-
- private static final DocumentColor PRIMARY = DocumentColor.rgb(24, 35, 51);
- private static final DocumentColor BODY = DocumentColor.rgb(49, 58, 72);
- private static final DocumentColor ACCENT = DocumentColor.rgb(172, 112, 55);
-
- private ExecutiveLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code Executive} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Executive Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.POPPINS)
- .size(24.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(PRIMARY)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.0)
- .color(BODY)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.5)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.5)
- .color(BODY)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java
deleted file mode 100644
index f3e1359b0..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 "Modern Professional Letter" cover-letter preset.
- *
- *
Visual pair of
- * {@link com.demcha.compose.document.templates.cv.presets.ModernProfessional}.
- * Same right-aligned header (slate-blue name, royal-blue underlined
- * contact links), same Helvetica body type. The cover letter itself
- * is a single-column letter — header on top, greeting, body
- * paragraphs separated by paragraph spacing, closing.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ModernProfessionalLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class ModernProfessionalLetter {
-
- /** Stable template identifier. */
- public static final String ID = "modern-professional-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Modern Professional Letter";
-
- /** V1 {@code BrandTheme} primary slate-blue used by the display name. */
- private static final DocumentColor NAME_COLOR = DocumentColor.rgb(44, 62, 80);
-
- /** V1 link accent (royal blue) used by the contact link row. */
- private static final DocumentColor LINK_COLOR = DocumentColor.rgb(65, 105, 225);
-
- private ModernProfessionalLetter() {
- }
-
- /**
- * Builds a fresh cover-letter template paired with the
- * Modern Professional CV style.
- *
- * @param theme active business theme
- * @return ready-to-use template
- * @throws NullPointerException if {@code theme} is null
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.compact();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA_BOLD)
- .size(28.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(NAME_COLOR)
- .build();
-
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(9.0)
- .color(theme.text().body().color())
- .build();
-
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(10.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(LINK_COLOR)
- .build();
-
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.HELVETICA)
- .size(10.0)
- .color(theme.text().body().color())
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID)
- .displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout()
- .moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle)
- .spacing(spacing)
- .build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java
deleted file mode 100644
index b37b3d18e..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code MonogramSidebar} CV preset.
- *
- *
Crimson Text headline + Lato body, deep slate ink with muted gold
- * accent — matches
- * {@link com.demcha.compose.document.templates.cv.presets.MonogramSidebar}.
- * The cover letter is a simple single-column letter — the CV's
- * monogram sidebar is intentionally not replicated.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.MonogramSidebarLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class MonogramSidebarLetter {
-
- /** Stable template identifier. */
- public static final String ID = "monogram-sidebar-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Monogram Sidebar Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(37, 45, 58);
- private static final DocumentColor SOFT = DocumentColor.rgb(112, 119, 125);
- private static final DocumentColor ACCENT = DocumentColor.rgb(158, 146, 104);
-
- private MonogramSidebarLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code MonogramSidebar} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Monogram Sidebar Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.CRIMSON_TEXT)
- .size(26.0)
- .decoration(DocumentTextDecoration.DEFAULT)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(7.4)
- .color(SOFT)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(7.4)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.5)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java
deleted file mode 100644
index 7b53d52af..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code NordicClean} CV preset.
- *
- *
Same INK / ACCENT palette and Barlow + Lato typography as the
- * {@link com.demcha.compose.document.templates.cv.presets.NordicClean}
- * CV. Single-column letter format — header on top, greeting, body
- * paragraphs, closing.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.PanelLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class PanelLetter {
-
- /** Stable template identifier. */
- public static final String ID = "panel-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Panel Letter";
-
- private static final DocumentColor HEADER_TEXT = DocumentColor.rgb(20, 44, 66);
- private static final DocumentColor BODY = DocumentColor.rgb(54, 68, 84);
- private static final DocumentColor ACCENT = DocumentColor.rgb(0, 128, 128);
-
- private PanelLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code Panel} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Panel Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.POPPINS)
- .size(22.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(HEADER_TEXT)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.9)
- .color(BODY)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.9)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.4)
- .color(BODY)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java
deleted file mode 100644
index 5da97e3a7..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code SidebarPortrait} CV preset.
- *
- *
Crimson Text serif headline + Lato body in the restrained grey
- * palette of
- * {@link com.demcha.compose.document.templates.cv.presets.SidebarPortrait}.
- * The cover letter is a simple single-column letter — the CV's
- * portrait sidebar is intentionally not replicated.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.SidebarPortraitLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class SidebarPortraitLetter {
-
- /** Stable template identifier. */
- public static final String ID = "sidebar-portrait-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Sidebar Portrait Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(34, 34, 34);
- private static final DocumentColor SOFT = DocumentColor.rgb(85, 85, 85);
- private static final DocumentColor ACCENT = DocumentColor.rgb(106, 106, 106);
-
- private SidebarPortraitLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code SidebarPortrait} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Sidebar Portrait Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.CRIMSON_TEXT)
- .size(28.0)
- .decoration(DocumentTextDecoration.BOLD)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.3)
- .color(SOFT)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.3)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(ACCENT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java
deleted file mode 100644
index fbf27f9f7..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.presets;
-
-import com.demcha.compose.document.style.DocumentColor;
-import com.demcha.compose.document.style.DocumentTextDecoration;
-import com.demcha.compose.document.style.DocumentTextStyle;
-import com.demcha.compose.document.templates.api.DocumentTemplate;
-import com.demcha.compose.document.templates.components.Header;
-import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder;
-import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat;
-import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec;
-import com.demcha.compose.document.templates.themes.Spacing;
-import com.demcha.compose.document.theme.BusinessTheme;
-import com.demcha.compose.font.FontName;
-
-/**
- * Templates v2 cover-letter pair for {@code TimelineMinimal} CV preset.
- *
- *
All-grey palette with Barlow Condensed for the headline and Lato
- * body — matches
- * {@link com.demcha.compose.document.templates.cv.presets.TimelineMinimal}.
- *
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard). Kept for backward compatibility; scheduled for removal
- * in a future major. See {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.presets.TimelineMinimalLetter}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public final class TimelineMinimalLetter {
-
- /** Stable template identifier. */
- public static final String ID = "timeline-minimal-letter";
-
- /** Human-readable display name. */
- public static final String DISPLAY_NAME = "Timeline Minimal Letter";
-
- private static final DocumentColor INK = DocumentColor.rgb(74, 74, 74);
- private static final DocumentColor SOFT = DocumentColor.rgb(122, 122, 122);
-
- private TimelineMinimalLetter() {
- }
-
- /**
- * Builds the cover-letter template paired with the {@code TimelineMinimal} CV preset.
- *
- * @param theme the active theme supplying palette, typography, and spacing
- * @return a {@code DocumentTemplate} for the "Timeline Minimal Letter"
- */
- public static DocumentTemplate create(BusinessTheme theme) {
- Spacing spacing = Spacing.comfortable();
-
- DocumentTextStyle nameStyle = DocumentTextStyle.builder()
- .fontName(FontName.BARLOW_CONDENSED)
- .size(28.0)
- .decoration(DocumentTextDecoration.DEFAULT)
- .color(INK)
- .build();
- DocumentTextStyle contactStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(8.5)
- .color(SOFT)
- .build();
- DocumentTextStyle linkStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(9.0)
- .decoration(DocumentTextDecoration.UNDERLINE)
- .color(SOFT)
- .build();
- DocumentTextStyle bodyStyle = DocumentTextStyle.builder()
- .fontName(FontName.LATO)
- .size(10.0)
- .color(INK)
- .build();
-
- return CoverLetterBuilder.builder()
- .id(ID).displayName(DISPLAY_NAME)
- .header(Header.rightAligned(theme, spacing)
- .withNameStyle(nameStyle)
- .withContactStyle(contactStyle)
- .withLinkStyle(linkStyle))
- .layout(LetterFormat.layout().moduleGap(spacing.moduleGap()))
- .bodyStyle(bodyStyle).spacing(spacing).build();
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java
deleted file mode 100644
index 0bea3e7c8..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Superseded Gen-2 cover-letter presets — flat copy-and-tweak recipe
- * classes paired one-to-one with the
- * {@link com.demcha.compose.document.templates.cv.presets} CV
- * preset family.
- *
- *
Deprecated surface. These are the older Gen-2
- * cover-letter presets. They are not the current standard. The
- * current standard is the layered surface
- * {@code com.demcha.compose.document.templates.coverletter.v2.presets}. This
- * package is kept only for backward compatibility and is scheduled for
- * removal in a future major.
- *
- *
Each preset shares the typography palette and spacing rhythm
- * of its paired CV preset, so a writer's CV and cover letter ship
- * as a matched set with consistent visual identity.
- *
- *
New code should target the layered {@code coverletter.v2} presets
- * instead. See {@code docs/templates/v2-layered/}.
Mirrors {@code CvHeader} structurally because the user-facing
- * concept (name, address, phone, email, links) is identical. The
- * domain types are kept separate so the cover-letter and CV
- * surfaces can evolve independently if needed.
- *
- * @param name document subject's name (required, non-blank)
- * @param address optional address line; empty string when absent
- * @param phone optional phone number; empty string when absent
- * @param email optional email address; empty string when absent
- * @param links ordered list of {@link Link} entries (typically
- * LinkedIn, GitHub); never null after construction
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard) — the layered model
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}
- * plus the {@code coverletter.v2} presets. Kept for backward
- * compatibility; scheduled for removal in a future major. See
- * {@code docs/templates/v2-layered/}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public record CoverLetterHeader(
- String name,
- String address,
- String phone,
- String email,
- List links) {
-
- /**
- * Compact constructor that normalises null strings to empty and
- * defensively copies the link list.
- *
- * @throws NullPointerException if {@code name} is null
- * @throws IllegalArgumentException if {@code name} is blank
- */
- public CoverLetterHeader {
- Objects.requireNonNull(name, "name");
- if (name.isBlank()) {
- throw new IllegalArgumentException("name must not be blank");
- }
- address = address == null ? "" : address;
- phone = phone == null ? "" : phone;
- email = email == null ? "" : email;
- links = links == null ? List.of() : List.copyOf(links);
- }
-
- /**
- * Returns the contact items (address, phone) in source order,
- * skipping blank fields.
- *
- * @return ordered list of non-blank contact strings
- */
- public List contactItems() {
- java.util.List items = new java.util.ArrayList<>(2);
- if (!address.isBlank()) {
- items.add(address);
- }
- if (!phone.isBlank()) {
- items.add(phone);
- }
- return List.copyOf(items);
- }
-
- /**
- * Returns a fresh builder.
- *
- * @return new builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Named hyperlink in a cover letter header (e.g. LinkedIn).
- *
- * @param label visible label (must not be blank)
- * @param url target URL (may be empty for non-clickable label)
- */
- public record Link(String label, String url) {
-
- /**
- * Compact constructor that rejects null fields.
- *
- * @throws NullPointerException if {@code label} or {@code url} is null
- * @throws IllegalArgumentException if {@code label} is blank
- */
- public Link {
- Objects.requireNonNull(label, "label");
- Objects.requireNonNull(url, "url");
- if (label.isBlank()) {
- throw new IllegalArgumentException("label must not be blank");
- }
- }
- }
-
- /**
- * Mutable builder for {@link CoverLetterHeader}.
- */
- public static final class Builder {
- private String name;
- private String address = "";
- private String phone = "";
- private String email = "";
- private final java.util.List links = new java.util.ArrayList<>();
-
- private Builder() {
- }
-
- /**
- * Sets the document subject's name.
- *
- * @param value non-blank name
- * @return this builder
- */
- public Builder name(String value) {
- this.name = value;
- return this;
- }
-
- /**
- * Sets the optional address line.
- *
- * @param value address; null treated as empty
- * @return this builder
- */
- public Builder address(String value) {
- this.address = value == null ? "" : value;
- return this;
- }
-
- /**
- * Sets the optional phone number.
- *
- * @param value phone; null treated as empty
- * @return this builder
- */
- public Builder phone(String value) {
- this.phone = value == null ? "" : value;
- return this;
- }
-
- /**
- * Sets the optional email address.
- *
- * @param value email; null treated as empty
- * @return this builder
- */
- public Builder email(String value) {
- this.email = value == null ? "" : value;
- return this;
- }
-
- /**
- * Appends a labelled link.
- *
- * @param label non-blank link label
- * @param url non-null target URL (may be empty)
- * @return this builder
- */
- public Builder link(String label, String url) {
- this.links.add(new Link(label, url));
- return this;
- }
-
- /**
- * Builds an immutable {@link CoverLetterHeader}.
- *
- * @return new cover letter header
- */
- public CoverLetterHeader build() {
- return new CoverLetterHeader(name, address, phone, email, links);
- }
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java b/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java
deleted file mode 100644
index ba8ae9acd..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package com.demcha.compose.document.templates.coverletter.spec;
-
-import java.util.List;
-import java.util.Objects;
-
-/**
- * User-facing data record for a cover letter in Templates v2.
- *
- *
A cover letter is structurally simpler than a CV: a header
- * identifying the writer, a greeting line ({@code "Dear Hiring
- * Manager,"}), a sequence of body paragraphs, and a closing line
- * ({@code "Sincerely, Artem"}). Each segment is rendered by the
- * paired preset using the same typography palette as its CV
- * counterpart so a writer can ship a CV and matching cover letter
- * with consistent visual identity.
- *
- * @param header identity block (required)
- * @param greeting first body line (required, may be blank to
- * suppress); typically {@code "Dear Hiring
- * Manager,"}
- * @param bodyParagraphs ordered list of body paragraphs; blank
- * paragraphs are kept to preserve the
- * writer's intended whitespace; may carry
- * markdown markers ({@code **bold**},
- * {@code *italic*})
- * @param closing last body line (required, may be blank);
- * typically {@code "Sincerely, Alex"}
- * @deprecated Superseded by the layered …v2… surface (the current
- * standard) — the layered model
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}
- * plus the {@code coverletter.v2} presets. Kept for backward
- * compatibility; scheduled for removal in a future major. See
- * {@code docs/templates/v2-layered/}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public record CoverLetterSpec(
- CoverLetterHeader header,
- String greeting,
- List bodyParagraphs,
- String closing) {
-
- /**
- * Compact constructor that normalises null strings to empty and
- * defensively copies the body paragraphs list.
- *
- * @throws NullPointerException if {@code header} or {@code bodyParagraphs} is null
- */
- public CoverLetterSpec {
- Objects.requireNonNull(header, "header");
- Objects.requireNonNull(bodyParagraphs, "bodyParagraphs");
- greeting = greeting == null ? "" : greeting;
- closing = closing == null ? "" : closing;
- bodyParagraphs = List.copyOf(bodyParagraphs);
- }
-
- /**
- * Returns a fluent builder.
- *
- * @return new builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Mutable builder for {@link CoverLetterSpec}.
- */
- public static final class Builder {
- private CoverLetterHeader header;
- private String greeting = "";
- private final java.util.List bodyParagraphs = new java.util.ArrayList<>();
- private String closing = "";
-
- private Builder() {
- }
-
- /**
- * Sets the document header.
- *
- * @param value non-null header
- * @return this builder
- */
- public Builder header(CoverLetterHeader value) {
- this.header = value;
- return this;
- }
-
- /**
- * Sets the greeting line.
- *
- * @param value greeting; null treated as empty
- * @return this builder
- */
- public Builder greeting(String value) {
- this.greeting = value == null ? "" : value;
- return this;
- }
-
- /**
- * Appends one body paragraph.
- *
- * @param value non-null paragraph text
- * @return this builder
- */
- public Builder paragraph(String value) {
- Objects.requireNonNull(value, "paragraph");
- this.bodyParagraphs.add(value);
- return this;
- }
-
- /**
- * Sets the closing line.
- *
- * @param value closing; null treated as empty
- * @return this builder
- */
- public Builder closing(String value) {
- this.closing = value == null ? "" : value;
- return this;
- }
-
- /**
- * Builds an immutable {@link CoverLetterSpec}.
- *
- * @return new spec
- */
- public CoverLetterSpec build() {
- return new CoverLetterSpec(header, greeting, bodyParagraphs, closing);
- }
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java
deleted file mode 100644
index ea846a961..000000000
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Superseded Gen-2 cover-letter specification records — user-facing data
- * types.
- *
- *
Deprecated surface. These are the older Gen-2
- * cover-letter spec records. They are not the current standard. The
- * current standard is the layered model
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}
- * in the {@code com.demcha.compose.document.templates.coverletter.v2}
- * surface. This package is kept only for backward compatibility and is
- * scheduled for removal in a future major.
- *
- *
This package holds the immutable records a user fills with their
- * cover-letter content before passing the spec to a Gen-2 preset for
- * rendering:
{@link com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec}
- * — header plus greeting, body paragraphs, and closing line.
- * Body strings may carry markdown markers ({@code **bold**},
- * {@code *italic*}) for inline emphasis.
- *
- *
- *
New code should target the layered {@code coverletter.v2} data model
- * instead. See {@code docs/templates/v2-layered/}.
Authoring role: keeps cover-letter composition document-shaped:
- * one header, one body, and optional job context for personalization.
- *
- * @param header contact/profile header rendered before the letter body
- * @param body cover-letter body text
- * @param jobDetails target role metadata used by templates
- * @author Artem Demchyshyn
- * @deprecated Test-only dead code; the live CV/cover-letter model is
- * {@code cv.v2} / {@code coverletter.v2}. Kept for backward
- * compatibility; scheduled for removal in a future major. See
- * {@code docs/templates/v2-layered/} and
- * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}.
- */
-@Deprecated(since = "1.7.0", forRemoval = true)
-public record CoverLetterDocumentSpec(
- Header header,
- String body,
- JobDetails jobDetails
-) {
-
- /**
- * Creates a normalized cover-letter spec.
- */
- public CoverLetterDocumentSpec {
- body = Objects.requireNonNullElse(body, "");
- }
-
- /**
- * Creates a document spec from the common cover-letter inputs.
- *
- * @param header contact/profile header
- * @param body cover-letter body text
- * @param jobDetails target role metadata
- * @return document spec
- */
- public static CoverLetterDocumentSpec of(Header header, String body, JobDetails jobDetails) {
- return new CoverLetterDocumentSpec(header, body, jobDetails);
- }
-
- /**
- * Starts a fluent cover-letter spec builder.
- *
- * @return document builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Builder for cover-letter document specs.
- */
- public static final class Builder {
- private Header header;
- private String body;
- private JobDetails jobDetails;
-
- private Builder() {
- }
-
- /**
- * Sets the contact/profile header.
- *
- * @param header header block
- * @return this builder
- */
- public Builder header(Header header) {
- this.header = header;
- return this;
- }
-
- /**
- * Configures the contact/profile header.
- *
- * @param spec header builder callback
- * @return this builder
- */
- public Builder header(Consumer spec) {
- Header.Builder builder = Header.builder();
- if (spec != null) {
- spec.accept(builder);
- }
- return header(builder.build());
- }
-
- /**
- * Sets the cover-letter body.
- *
- * @param body body text
- * @return this builder
- */
- public Builder body(String body) {
- this.body = body;
- return this;
- }
-
- /**
- * Alias for {@link #body(String)}.
- *
- * @param body body text
- * @return this builder
- */
- public Builder letter(String body) {
- return body(body);
- }
-
- /**
- * Sets the job details.
- *
- * @param jobDetails job metadata
- * @return this builder
- */
- public Builder jobDetails(JobDetails jobDetails) {
- this.jobDetails = jobDetails;
- return this;
- }
-
- /**
- * Configures the job details.
- *
- * @param spec job details builder callback
- * @return this builder
- */
- public Builder job(Consumer spec) {
- JobDetails.Builder builder = JobDetails.builder();
- if (spec != null) {
- spec.accept(builder);
- }
- return jobDetails(builder.build());
- }
-
- /**
- * Builds the immutable cover-letter spec.
- *
- * @return cover-letter document spec
- */
- public CoverLetterDocumentSpec build() {
- return new CoverLetterDocumentSpec(header, body, jobDetails);
- }
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java b/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java
deleted file mode 100644
index fba48c7d3..000000000
--- a/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package com.demcha.compose.document.templates.data.coverletter;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-
-/**
- * Immutable job-application context passed into canonical cover-letter composition.
- *
- *
Pipeline role: captures the target role, company, and optional job
- * posting metadata so template composers can resolve letter copy and chrome.
- *
- *
Mutability: immutable record. Thread-safety: thread-safe
- * when referenced through immutable component values.
- *
- * @param url optional job posting URL
- * @param title target role title
- * @param company target company name
- * @param location target job location
- * @param description optional job description text
- * @param seniorityLevel optional seniority label
- * @param employmentType optional employment type label
- */
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public record JobDetails(
- String url,
- String title,
- String company,
- String location,
- String description,
- String seniorityLevel,
- String employmentType) {
-
- /**
- * Starts a fluent job details builder.
- *
- * @return job details builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * Fluent builder for job details.
- */
- public static final class Builder {
- private String url;
- private String title;
- private String company;
- private String location;
- private String description;
- private String seniorityLevel;
- private String employmentType;
-
- private Builder() {
- }
-
- /**
- * Sets the job posting URL.
- *
- * @param url job posting URL
- * @return this builder
- */
- public Builder url(String url) {
- this.url = url;
- return this;
- }
-
- /**
- * Sets the target role title.
- *
- * @param title role title
- * @return this builder
- */
- public Builder title(String title) {
- this.title = title;
- return this;
- }
-
- /**
- * Sets the company name.
- *
- * @param company company name
- * @return this builder
- */
- public Builder company(String company) {
- this.company = company;
- return this;
- }
-
- /**
- * Sets the job location.
- *
- * @param location job location
- * @return this builder
- */
- public Builder location(String location) {
- this.location = location;
- return this;
- }
-
- /**
- * Sets the job description text.
- *
- * @param description job description text
- * @return this builder
- */
- public Builder description(String description) {
- this.description = description;
- return this;
- }
-
- /**
- * Sets the seniority label.
- *
- * @param seniorityLevel seniority label
- * @return this builder
- */
- public Builder seniorityLevel(String seniorityLevel) {
- this.seniorityLevel = seniorityLevel;
- return this;
- }
-
- /**
- * Sets the employment type label.
- *
- * @param employmentType employment type label
- * @return this builder
- */
- public Builder employmentType(String employmentType) {
- this.employmentType = employmentType;
- return this;
- }
-
- /**
- * Builds immutable job details.
- *
- * @return job details
- */
- public JobDetails build() {
- return new JobDetails(
- url,
- title,
- company,
- location,
- description,
- seniorityLevel,
- employmentType);
- }
- }
-}
diff --git a/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java b/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java
deleted file mode 100644
index 30e6a8b6a..000000000
--- a/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * Cover-letter document specs and supporting data records for canonical templates.
- */
-package com.demcha.compose.document.templates.data.coverletter;
diff --git a/src/main/java/com/demcha/compose/document/templates/data/package-info.java b/src/main/java/com/demcha/compose/document/templates/data/package-info.java
index 03f4e01c3..84f1013d7 100644
--- a/src/main/java/com/demcha/compose/document/templates/data/package-info.java
+++ b/src/main/java/com/demcha/compose/document/templates/data/package-info.java
@@ -3,8 +3,8 @@
* {@code document.templates} layer.
*
*
Concrete public data types live in child packages such as
- * {@code data.cv}, {@code data.invoice}, {@code data.proposal},
- * {@code data.coverletter}, and {@code data.schedule}. Shared contact/link
- * types live in {@code data.common}.
+ * {@code data.cv}, {@code data.invoice}, {@code data.proposal}, and
+ * {@code data.schedule}. Shared contact/link types live in
+ * {@code data.common}.
A snapshot mismatch means the preset's rendered tree drifted —
- * either intentionally (re-run with
- * {@code -Dgraphcompose.updateSnapshots=true}) or as a regression.
Each preset renders a fixed canonical {@link CoverLetterSpec} on
- * full A4 with the gallery-standard 48pt margin, the resulting PDF is
- * rasterized via PDFBox, and the per-pixel diff against a checked-in
- * baseline PNG is asserted to stay within the {@code PIXEL_DIFF_BUDGET}
- * mismatched-pixel budget at {@code PER_PIXEL_TOLERANCE} per-channel
- * colour tolerance. Re-run with
- * {@code -Dgraphcompose.visual.approve=true} to refresh the baselines
- * after a deliberate visual change.
- *
- *
Baselines live under
- * {@code src/test/resources/visual-baselines/coverletter-v2/}.