From 93eca0e95e7fa6bd782168abc5df3d584909feb0 Mon Sep 17 00:00:00 2001
From: DemchaAV
Date: Sun, 28 Jun 2026 11:35:56 +0100
Subject: [PATCH] docs(templates): point template docs at the extracted
templates.core
Update the current template docs to the post-extraction names: the CV
theme is BrandTheme in templates.core.theme, and the markdown/text
helpers, header widgets, and shared widgets live under templates.core.*.
- package-map: add core.theme/text/identity/widgets rows, fold the old
widgets+decorations entries into one core.widgets row, note MarkdownText
moved to core.text.
- v2-layered guides, AUTHORS, which-template-system, api-stability,
recipes, overview, CONTRIBUTING: CvTheme to BrandTheme,
cv.v2.theme to core.theme, and corrected widget package homes.
- coverletter package-info: the reused renderer is
core.text.RichParagraphRenderer.
Historical records (ADRs, CHANGELOG, migration guides) are left as
point-in-time records.
---
CONTRIBUTING.md | 2 +-
docs/api-stability.md | 6 +-
docs/architecture/overview.md | 6 +-
docs/architecture/package-map.md | 8 ++-
docs/recipes.md | 2 +-
docs/recipes/themes.md | 6 +-
docs/templates/v1-classic/README.md | 2 +-
.../templates/v2-layered/authoring-presets.md | 38 ++++++-----
.../templates/v2-layered/contributor-guide.md | 2 +-
docs/templates/v2-layered/quickstart.md | 12 ++--
docs/templates/v2-layered/using-templates.md | 44 ++++++-------
docs/templates/which-template-system.md | 8 +--
.../v2/components/package-info.java | 2 +-
.../document/templates/cv/v2/AUTHORS.md | 63 ++++++++++---------
14 files changed, 105 insertions(+), 96 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 455524a49..9597ea0cc 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -272,7 +272,7 @@ implementation; read it before starting yours.
variant alongside `ModernProfessional`, a new invoice preset
alongside `InvoiceTemplateV2`):
-- Constructor takes a `BusinessTheme` (or `CvTheme` for CV
+- Constructor takes a `BusinessTheme` (or `BrandTheme` for CV
templates). Provide a no-arg overload that picks a default theme.
- Compose against `DocumentDsl` — no PDF-specific imports.
- Route every visible token through `theme.palette()` /
diff --git a/docs/api-stability.md b/docs/api-stability.md
index 619406a8e..4332454a3 100644
--- a/docs/api-stability.md
+++ b/docs/api-stability.md
@@ -28,7 +28,7 @@ matrix.
| Tier | Marker | Used for | Breaking changes allowed in |
|---|---|---|---|
-| **Stable** | _(default — no annotation)_ | The canonical authoring surface that user code is meant to call: `GraphCompose.document(...)`, `DocumentSession`, `DocumentDsl`, `RowBuilder` / `SectionBuilder` / `ParagraphBuilder` and friends, `DocumentInsets` / `DocumentColor` / `DocumentTextStyle`, the `BusinessTheme` and `CvTheme` factories, the recommended template presets in `cv.v2.*` and `coverletter.v2.*`. | **Major releases only.** |
+| **Stable** | _(default — no annotation)_ | The canonical authoring surface that user code is meant to call: `GraphCompose.document(...)`, `DocumentSession`, `DocumentDsl`, `RowBuilder` / `SectionBuilder` / `ParagraphBuilder` and friends, `DocumentInsets` / `DocumentColor` / `DocumentTextStyle`, the `BusinessTheme` and `BrandTheme` factories, the recommended template presets in `cv.v2.*` and `coverletter.v2.*`. | **Major releases only.** |
| **Supported** | _(no annotation; called out in the page's Javadoc)_ | A canonical surface that ships through 1.x but won't be in 2.0 — its replacement is already the Stable path. The `cv.presets.*` "classic" CV preset surface is the only Supported tier in 1.x today (replaced by `cv.v2.*` per [`which-template-system.md`](templates/which-template-system.md)). Bug fixes + behaviour-preserving refactors only. | **Minor releases for behaviour-preserving refactors; removed wholesale in 2.0.** |
| **Extension SPI** | [`@Beta`](../src/main/java/com/demcha/compose/document/api/Beta.java) | Public extension points that authors are expected to **implement**, not only call: render-handler interfaces, [`NodeDefinition`](../src/main/java/com/demcha/compose/document/layout/NodeDefinition.java), custom `Theme` subtype contracts, fragment payload interfaces designed for extension. | Minor releases, with a one-minor deprecation window where possible. |
| **Experimental** | [`@Beta`](../src/main/java/com/demcha/compose/document/api/Beta.java) _(same annotation as Extension SPI; the distinction lives in the docstring on the annotated element)_ | A brand-new public type shipping in its first minor release before its contract has stabilised. The contract is in active flux. | Any minor release, including removal. No deprecation window. |
@@ -178,7 +178,7 @@ window starts, and its `Status` flips to `deprecated 1.x`.
|---|---|---|---|---|---|---|
| `DocumentSession.pageMargins(List)` / `PageMarginRule` | Stable | planned | Per-page margins resolve a block's content width by the page it *begins* on (the engine measures each block once, before pagination). A margin that changes the content width therefore does not re-wrap a block mid-flow across a page boundary. | Revisit a page-aware per-line/per-fragment width model so a block can re-wrap when it crosses a margin boundary, if demand warrants. | — | — |
| `templates.api.CoverLetterTemplate` | Stable | deprecated 1.9 | Orphan interface — nothing implements it; cover-letter presets implement the generic `DocumentTemplate` seam. | Remove; callers implement `DocumentTemplate`. | — | — |
-| `templates.cv.v2.components.HeadlineRenderer` / `ContactRenderer` / `BannerRenderer` | Stable | deprecated 1.9 | Pre-widgets delegating shims superseded by the `cv.v2.widgets` `Headline` / `ContactLine` / `SectionHeader` widgets; no callers. | Remove; use the widgets. | — | — |
+| `templates.cv.v2.components.HeadlineRenderer` / `ContactRenderer` / `BannerRenderer` | Stable | deprecated 1.9 | Pre-widgets delegating shims superseded by the `Headline` / `ContactLine` / `SectionHeader` widgets; no callers. | Remove; use the widgets. | — | — |
---
@@ -194,7 +194,7 @@ Javadoc per element.
| `com.demcha.compose.document.dsl` | **Stable** | All builder types (`RowBuilder`, `SectionBuilder`, `ParagraphBuilder`, etc.). |
| `com.demcha.compose.document.node` | **Stable** | Node records (`RowNode`, `SectionNode`, `ParagraphNode`, ...). Sealed where relevant — see § 2. |
| `com.demcha.compose.document.style` | **Stable** | `DocumentColor`, `DocumentInsets`, `DocumentTextStyle`, `DocumentTransform`, ... |
-| `com.demcha.compose.document.templates.cv.v2.*` | **Stable** | Layered CV presets, `CvDocument`, `CvTheme`. Recommended template surface. |
+| `com.demcha.compose.document.templates.cv.v2.*` | **Stable** | Layered CV presets, `CvDocument`, `BrandTheme`. Recommended template surface. |
| `com.demcha.compose.document.templates.coverletter.v2.*` | **Stable** | Layered cover-letter presets. |
| `com.demcha.compose.document.templates.builtins` | **Stable** | `InvoiceTemplateV2`, `ProposalTemplateV2`, `BusinessTheme`. |
| `com.demcha.compose.document.templates.cv.presets.*` | **Stable but Supported** | The "classic" v1.6 rebuild surface. See [`which-template-system.md`](templates/which-template-system.md). Supported through 1.x; removed in 2.0. |
diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md
index f6da7b89c..dcdf1201f 100644
--- a/docs/architecture/overview.md
+++ b/docs/architecture/overview.md
@@ -93,8 +93,8 @@ need to reach below it.
(`DocumentImageData`, `DocumentImageFitMode`).
- **`document.theme`** — `BusinessTheme` design tokens
(`DocumentPalette`, `SpacingScale`, `TextScale`, `TablePreset`). The
- layered CV theme `CvTheme` lives separately under
- `…templates.cv.v2.theme`.
+ layered CV theme `BrandTheme` lives separately under
+ `…templates.core.theme`.
- **`document.output`** — backend-neutral output options
(`DocumentMetadata`, `DocumentWatermark`, `DocumentProtection`,
`DocumentHeaderFooter`).
@@ -128,7 +128,7 @@ the same `DocumentDsl` an application would use directly.
- **`...templates.builtins`** — concrete built-ins
(`InvoiceTemplateV1`, `InvoiceTemplateV2`, `ProposalTemplateV1`,
`ProposalTemplateV2`, `CvTemplateV1`, plus a CV gallery that takes a
- `BusinessTheme` or `CvTheme` in their constructor).
+ `BusinessTheme` or `BrandTheme` in their constructor).
- **`...templates.support`** — backend-neutral scene composers per
domain (`...support.cv`, `...support.business`, `...support.schedule`)
plus shared composition primitives in `...support.common`.
diff --git a/docs/architecture/package-map.md b/docs/architecture/package-map.md
index cdebd0d7f..b86a2d87d 100644
--- a/docs/architecture/package-map.md
+++ b/docs/architecture/package-map.md
@@ -68,10 +68,12 @@ intended.
| `com.demcha.compose.document.templates.support.schedule` | Schedule-specific scene composer. | Keep schedule-specific table/rhythm decisions isolated here. |
| `com.demcha.compose.document.templates.theme` | Older shared theme *objects* for built-ins (e.g. `WeeklyScheduleTheme`). Distinct from `…templates.themes` (plural) below. | Themes carry styling decisions, not document content. New v2 token work goes in `themes`, not here. |
| `com.demcha.compose.document.templates.themes` | Templates-v2 theme *token records* — `Spacing`, `Typography` (future `Palette`). Pure value types, no engine / session dependencies. | One source of truth per token group; keep it dependency-free. |
-| `com.demcha.compose.document.templates.components` | Templates-v2 reusable composition components shared across families — `Header`, `Module`, `MarkdownText`. | Stateless after construction; produce `DocumentNode`s. Family-specific components go in `.v2.components`. |
+| `com.demcha.compose.document.templates.components` | Gen-2 composition components — `Header`, `Module` (`MarkdownText` moved to `core.text`). | Stateless after construction; produce `DocumentNode`s. |
| `com.demcha.compose.document.templates.blocks` | Templates-v2 module-body block kinds — `ParagraphBlock`, `BulletListBlock`, `NumberedListBlock`, `IndentedBlock`, `KeyValueBlock`, `MultiParagraphBlock`, `EducationBlock`, `WorkHistoryBlock`. | A block declares *what* content appears; the renderer expands it per active theme / tokens. |
-| `com.demcha.compose.document.templates.decorations` | Templates-v2 decoration library — `Divider`, `AccentStrip`, `Spacer` (Panel / Banner / Ornament reserved). | First-class artefacts any preset can attach; not baked into composer logic. |
-| `com.demcha.compose.document.templates.widgets` | Shared visual widgets usable by every family — `CardWidget`, `TableWidget`, `TimelineAxisWidget`. | Keep generic (no CV-only assumptions) so invoice / proposal / cover-letter can reuse them. |
+| `com.demcha.compose.document.templates.core.theme` | Family-neutral theme tokens — `BrandTheme` + `Palette` / `Typography` / `Spacing` / `Decoration`. | The single token source every family's presets read. |
+| `com.demcha.compose.document.templates.core.text` | Family-neutral text rendering — `MarkdownText`, `MarkdownInline`, `RichParagraphRenderer`, `TextStyles`, `TextOrnaments`. | Markdown → DSL nodes; no family data model. |
+| `com.demcha.compose.document.templates.core.identity` | Family-neutral identity — `PartyIdentity` contract + header widgets (`Headline`, `ContactLine`, `Masthead`, `Subheadline`, `SvgGlyph`) + `Contact` / `Link`. | A masthead is the same shape in every family. |
+| `com.demcha.compose.document.templates.core.widgets` | Family-neutral shared widgets + decoration primitives — `CardWidget`, `TableWidget`, `TimelineAxisWidget`, `Divider`, `AccentStrip`, `Spacer`. | Keep generic (no CV-only assumptions) so any family can reuse them. |
> **Preset families.** Concrete document families live under `…templates.` — `cv`, `coverletter`, `invoice`, `proposal`, `schedule`. CV and cover letter additionally ship a layered v2 surface (`…cv.v2.*` / `…coverletter.v2.*`: `data` / `theme` / `components` / `widgets` / `presets`). These per-family packages are documented by the template guides rather than enumerated here — see [which-template-system.md](../templates/which-template-system.md) for the status matrix and [templates/v2-layered/](../templates/v2-layered/README.md) for the layered architecture.
diff --git a/docs/recipes.md b/docs/recipes.md
index 821748f86..2f45369ef 100644
--- a/docs/recipes.md
+++ b/docs/recipes.md
@@ -11,7 +11,7 @@ authoring API; public application code should not import
| --- | --- |
| [Charts](recipes/charts.md) | Native vector bar / line / area / pie-donut charts: data–spec–style layers, axis & grid toggles, point markers, value-label halos, legend placement, translucent area fills |
| [Keep-together pagination](recipes/keep-together.md) | `keepTogether()` / `keepEntriesTogether()` — blocks that relocate whole instead of orphaning a heading at a page break |
-| [Themes](recipes/themes.md) | `BusinessTheme.classic / modern / executive`, page background, palette slots, text scale, the `CvTheme` ↔ `BusinessTheme` bridge |
+| [Themes](recipes/themes.md) | `BusinessTheme.classic / modern / executive`, page background, palette slots, text scale, the `BrandTheme` ↔ `BusinessTheme` bridge |
| [Shapes and visual primitives](recipes/shapes.md) | Filled cards, dividers, spacers, lines, ellipses, image fit modes, soft panels |
| [Shape-as-container](recipes/shape-as-container.md) | `addCircle` / `addEllipse` / `addContainer` with `ClipPolicy` (clipped layered children) |
| [Transforms and z-index](recipes/transforms.md) | `rotate` / `scale` mixin, per-layer `zIndex` for overlays |
diff --git a/docs/recipes/themes.md b/docs/recipes/themes.md
index 8bda10c86..8103db77e 100644
--- a/docs/recipes/themes.md
+++ b/docs/recipes/themes.md
@@ -103,8 +103,8 @@ side; V2 is the cinematic theme-driven path.
## CV themes
CV templates are themed independently of `BusinessTheme`. The layered
-CV presets (`cv.v2.presets.*`) carry their own theme type, `CvTheme`
-(in `com.demcha.compose.document.templates.cv.v2.theme`), so CV tokens
+CV presets (`cv.v2.presets.*`) carry their own theme type, `BrandTheme`
+(in `com.demcha.compose.document.templates.core.theme`), so CV tokens
stay separate from invoice / proposal vocabulary. Each preset ships a
default theme; render one against a `CvDocument` with its `create()`
factory:
@@ -118,7 +118,7 @@ DocumentTemplate cv = ModernProfessional.create();
cv.compose(session, cvDocument);
```
-To restyle, pass a custom `CvTheme` to the preset's `create(...)`
+To restyle, pass a custom `BrandTheme` to the preset's `create(...)`
overload, or use its `Options` builder where one is provided (for
example `MintEditorial.Options.builder().headerBandColor(...).build()`
→ `MintEditorial.create(options)`). See
diff --git a/docs/templates/v1-classic/README.md b/docs/templates/v1-classic/README.md
index f1ee9bce1..6d7de6929 100644
--- a/docs/templates/v1-classic/README.md
+++ b/docs/templates/v1-classic/README.md
@@ -121,7 +121,7 @@ copy-and-tweak entry point for callers extending their own branding.
## Authoring features built into every preset
-- **Inline markdown** — body strings carrying `**bold**` and `*italic*` markers render with proper `DocumentTextDecoration` via `templates.components.MarkdownText`.
+- **Inline markdown** — body strings carrying `**bold**` and `*italic*` markers render with proper `DocumentTextDecoration` via `templates.core.text.MarkdownText`.
- **Active hyperlinks** — header email + LinkedIn / GitHub labels become clickable `mailto:` / `https:` runs via `DocumentLinkOptions`.
- **Slot-based layouts** — multi-column presets (`Panel`, `SidebarPortrait`, `MonogramSidebar`) declare named slots (`MAIN`, `SIDEBAR`); custom presets rearrange modules via `.place(slot, "Module Name", ...)`.
- **Adaptive sidebar fill** — sidebar layouts size the trailing spacer dynamically from `canvas().innerHeight()` so background panels reach the page bottom on A4 / Letter / smaller fixtures without overflow.
diff --git a/docs/templates/v2-layered/authoring-presets.md b/docs/templates/v2-layered/authoring-presets.md
index dd73154cd..712fb6ff9 100644
--- a/docs/templates/v2-layered/authoring-presets.md
+++ b/docs/templates/v2-layered/authoring-presets.md
@@ -60,11 +60,15 @@ visual decision you can read like a recipe.
## The widget catalog
-The CV widget classes live in
-`com.demcha.compose.document.templates.cv.v2.widgets`. Each has a
-small set of named variants. Generic widgets that can be reused by
-CVs, proposals, invoices, and cover letters live one package higher
-in `com.demcha.compose.document.templates.widgets`.
+The neutral header widgets — `Headline`, `Subheadline`, `ContactLine`,
+`Masthead`, `SvgGlyph` — live in
+`com.demcha.compose.document.templates.core.identity`. The CV-specific
+section widgets (`SectionHeader` and friends) stay in
+`com.demcha.compose.document.templates.cv.v2.widgets`. The generic
+`CardWidget` / `TableWidget` / `TimelineAxisWidget` reusable by CVs,
+proposals, invoices, and cover letters live in
+`com.demcha.compose.document.templates.core.widgets`. Each has a small
+set of named variants.
### `Headline` — top-of-document name
@@ -143,14 +147,14 @@ Used for the icon-led contact and social rows in sidebar CV layouts
The separator glyph used by `ContactLine`, the bullet glyph used by
`RowRenderer`, and other character-level choices come from
-`theme.decoration()` — swap a `CvDecoration` to change them
+`theme.decoration()` — swap a `Decoration` to change them
globally.
Some presets also expose narrow preset-specific options when the
visual decision is structural rather than a reusable widget. Example:
`NordicClean.Options` lets authors move the skills rail to the right
and override the accent colour, rail fill, or profile-band fill
-without mutating shared `CvTheme` defaults or changing other presets.
+without mutating shared `BrandTheme` defaults or changing other presets.
---
@@ -169,17 +173,17 @@ public final class MyPreset {
private MyPreset() { }
public static DocumentTemplate create() {
- return create(CvTheme.boxedClassic());
+ return create(BrandTheme.boxedClassic());
}
- public static DocumentTemplate create(CvTheme theme) {
+ public static DocumentTemplate create(BrandTheme theme) {
Objects.requireNonNull(theme, "theme");
return new Template(theme);
}
private static final class Template implements DocumentTemplate {
- private final CvTheme theme;
- Template(CvTheme theme) { this.theme = theme; }
+ private final BrandTheme theme;
+ Template(BrandTheme theme) { this.theme = theme; }
@Override public String id() { return ID; }
@Override public String displayName() { return DISPLAY_NAME; }
@@ -192,7 +196,7 @@ public final class MyPreset {
}
```
-Two factories (`create()` and `create(CvTheme)`), three constants
+Two factories (`create()` and `create(BrandTheme)`), three constants
(`ID`, `DISPLAY_NAME`, `RECOMMENDED_MARGIN`), one inner `Template`
class implementing `DocumentTemplate`. Stable.
@@ -216,18 +220,18 @@ public final class CardStyle {
private CardStyle() { }
public static DocumentTemplate create() {
- return create(CvTheme.boxedClassic());
+ return create(BrandTheme.boxedClassic());
}
- public static DocumentTemplate create(CvTheme theme) {
+ public static DocumentTemplate create(BrandTheme theme) {
Objects.requireNonNull(theme, "theme");
return new Template(theme);
}
private static final class Template implements DocumentTemplate {
- private final CvTheme theme;
- Template(CvTheme theme) { this.theme = theme; }
+ private final BrandTheme theme;
+ Template(BrandTheme theme) { this.theme = theme; }
@Override public String id() { return ID; }
@Override public String displayName() { return DISPLAY_NAME; }
@@ -365,7 +369,7 @@ When you do add a new widget:
2. **`public final class`** with a private constructor.
3. **1-3 named factories** + a lower-level `.render(...)` when useful.
4. **First parameter is always `SectionBuilder host`**.
-5. **Pass `CvTheme theme` when the widget reads shared tokens**;
+5. **Pass `BrandTheme theme` when the widget reads shared tokens**;
pass an explicit style only when the preset owns that unique style.
6. **No instance state** — all static, all stateless.
7. **JavaDoc the visual** — what does this look like? Who uses it?
diff --git a/docs/templates/v2-layered/contributor-guide.md b/docs/templates/v2-layered/contributor-guide.md
index 235c0052c..0abe53786 100644
--- a/docs/templates/v2-layered/contributor-guide.md
+++ b/docs/templates/v2-layered/contributor-guide.md
@@ -115,7 +115,7 @@ differ.
## Naming rules
- **Family prefix** on top-level records to avoid name collisions.
- CV uses `CvName`, `CvContact`, `CvTheme`. Invoice should use
+ CV uses `CvName`, `CvIdentity`, `CvSection`. Invoice should use
`InvoiceParty`, `InvoiceLine`, `InvoiceTheme`. Cover letter:
`CoverLetterRecipient`, `CoverLetterTheme`. Etc.
- **`Document`** for the root record. (`CvDocument`,
diff --git a/docs/templates/v2-layered/quickstart.md b/docs/templates/v2-layered/quickstart.md
index 6316806b7..a448f7e5e 100644
--- a/docs/templates/v2-layered/quickstart.md
+++ b/docs/templates/v2-layered/quickstart.md
@@ -11,7 +11,7 @@ GraphCompose's templates v2 (layered) gives you:
- **Records describing content** — `CvDocument`, `CvIdentity`,
`CvSection`. No styling, no rendering, just structured data.
-- **Themes describing visuals** — `CvTheme` (palette + typography +
+- **Themes describing visuals** — `BrandTheme` (palette + typography +
spacing + decoration). Swap a theme to change colours, fonts,
bullet glyphs without touching renderers.
- **Widgets as visual LEGO bricks** — `Headline`, `Subheadline`,
@@ -105,11 +105,11 @@ Same data, different visual. That's the layering.
▼ ▼
┌─────────────────────┐ ┌──────────────────────────────────┐
│ components/ │ │ theme/ │
-│ SectionDispatcher │ │ CvPalette (colours) │
-│ EntryRenderer │ │ CvTypography (fonts + sizes) │
-│ RowRenderer │ │ CvSpacing (margins + gaps) │
-│ ParagraphRenderer │ │ CvDecoration (bullet, sep) │
-│ + primitives │ │ CvTheme (bundle + factories) │
+│ SectionDispatcher │ │ Palette (colours) │
+│ EntryRenderer │ │ Typography (fonts + sizes) │
+│ RowRenderer │ │ Spacing (margins + gaps) │
+│ ParagraphRenderer │ │ Decoration (bullet, sep) │
+│ + primitives │ │ BrandTheme (bundle + factories) │
└─────────────────────┘ └──────────────────────────────────┘
│ renders into DSL
▼
diff --git a/docs/templates/v2-layered/using-templates.md b/docs/templates/v2-layered/using-templates.md
index e16292f29..12f53d391 100644
--- a/docs/templates/v2-layered/using-templates.md
+++ b/docs/templates/v2-layered/using-templates.md
@@ -27,7 +27,7 @@ it sets up the conceptual model in 5 minutes.
```java
CvDocument doc = …; // your content
-CvTheme theme = CvTheme.boxedClassic(); // optional override
+BrandTheme theme = BrandTheme.boxedClassic(); // optional override
DocumentTemplate tpl = BoxedSections.create(theme);
try (DocumentSession s = GraphCompose.document(path).create()) {
@@ -38,7 +38,7 @@ try (DocumentSession s = GraphCompose.document(path).create()) {
Three lines of "what":
- **`CvDocument`** — your content. Built via builder.
-- **`CvTheme`** — visual style. Use a shipped factory or build your own.
+- **`BrandTheme`** — visual style. Use a shipped factory or build your own.
- **A preset** — orchestrates them into a page flow.
---
@@ -203,11 +203,11 @@ Nine shipped today:
| `CompactMono.create()` | Dark command-bar header, pale left rail, same-width right-column cards |
Each factory has a no-arg form (uses a sensible default theme) and
-a `create(CvTheme)` form (custom theme).
+a `create(BrandTheme)` form (custom theme).
```java
BoxedSections.create() // default theme
-BoxedSections.create(CvTheme.boxedClassic()) // explicit
+BoxedSections.create(BrandTheme.boxedClassic()) // explicit
BoxedSections.create(myCustomTheme) // your own
```
@@ -218,7 +218,7 @@ band fill.
```java
NordicClean.create(
- CvTheme.nordicClean(),
+ BrandTheme.nordicClean(),
NordicClean.Options.builder()
.railSide(NordicClean.RailSide.RIGHT) // skills rail on the right
.accentColor(DocumentColor.rgb(40, 110, 120))
@@ -236,26 +236,26 @@ Themes are records made of four sub-records:
| Sub-record | What it controls |
|---|---|
-| `CvPalette` | Colours (`ink`, `muted`, `rule`, `banner`) |
-| `CvTypography` | Fonts + size scale (8 sizes + line spacing) |
-| `CvSpacing` | Margins, padding, weights, gaps |
-| `CvDecoration` | Bullet glyph, stacked indent, contact separator |
+| `Palette` | Colours (`ink`, `muted`, `rule`, `banner`) |
+| `Typography` | Fonts + size scale (8 sizes + line spacing) |
+| `Spacing` | Margins, padding, weights, gaps |
+| `Decoration` | Bullet glyph, stacked indent, contact separator |
**Swap one piece, keep the rest:**
```java
// Navy palette, classic everything else
-CvPalette navy = new CvPalette(
+Palette navy = new Palette(
DocumentColor.rgb(15, 34, 80), // ink — primary text
DocumentColor.rgb(90, 110, 150), // muted — italic subtitles
DocumentColor.rgb(120, 140, 180), // rule — separator lines
DocumentColor.rgb(220, 230, 240)); // banner — pale fill
-CvTheme navyTheme = new CvTheme(
+BrandTheme navyTheme = new BrandTheme(
navy,
- CvTypography.classic(),
- CvSpacing.classic(),
- CvDecoration.classic());
+ Typography.classic(),
+ Spacing.classic(),
+ Decoration.classic());
BoxedSections.create(navyTheme);
```
@@ -263,27 +263,27 @@ BoxedSections.create(navyTheme);
**Change a glyph** (bullet, separator):
```java
-CvDecoration arrowDecoration = new CvDecoration(
+Decoration arrowDecoration = new Decoration(
"▶ ", // bullet glyph
" ", // stacked-row second-line indent
" · "); // contact-line separator
-CvTheme theme = new CvTheme(
- CvPalette.classic(),
- CvTypography.classic(),
- CvSpacing.classic(),
+BrandTheme theme = new BrandTheme(
+ Palette.classic(),
+ Typography.classic(),
+ Spacing.classic(),
arrowDecoration);
```
**Change a font** (`Helvetica` instead of `PT Serif`):
```java
-CvTypography sans = new CvTypography(
+Typography sans = new Typography(
FontName.HELVETICA_BOLD, FontName.HELVETICA,
21.5, 8.5, 9.6, 9.2, 8.8, 8.4, 8.6, 1.4); // sizes per role
-CvTheme theme = new CvTheme(
- CvPalette.classic(), sans, CvSpacing.classic(), CvDecoration.classic());
+BrandTheme theme = new BrandTheme(
+ Palette.classic(), sans, Spacing.classic(), Decoration.classic());
```
For more recipes (compact spacing, alternative typography scales,
diff --git a/docs/templates/which-template-system.md b/docs/templates/which-template-system.md
index 2056a31c1..cf96a6204 100644
--- a/docs/templates/which-template-system.md
+++ b/docs/templates/which-template-system.md
@@ -107,13 +107,13 @@ plus a theme + data-record swap (introduced below):
-// before: CvSpec + BusinessTheme
-NordicClean.create(BusinessTheme.nordicClean()).render(session, cvSpec);
-+// after: CvDocument + CvTheme — see the two shape changes below
++// after: CvDocument + BrandTheme — see the two shape changes below
+NordicClean.create(cvTheme).render(session, cvDocument);
```
Two real shape changes accompany the swap:
-1. **Theme.** `BusinessTheme.X()` → `CvTheme.X()`. The CV-specific
+1. **Theme.** `BusinessTheme.X()` → `BrandTheme.X()`. The CV-specific
tokens (palette / typography / spacing) are split out so `cv.v2`
themes don't carry invoice / proposal vocabulary they don't use.
2. **Data record.** `CvSpec` → `CvDocument`. The data shape becomes
@@ -193,8 +193,8 @@ private taskboard.
| `DocumentSession.builder()` (deprecated alias) | Pre-rebuild builder entry point. | `GraphCompose.document()`. |
| `DocumentDsl.text(...)` (deprecated alias) | Pre-rebuild text shortcut. | `paragraph(...)` builders inside `pageFlow`. |
| `DocumentPalette.of(...)` (deprecated alias) | Pre-rebuild palette factory. | `DocumentPalette.from(...)` (or theme-specific factories). |
-| PDF-specific chrome overloads on `BusinessTheme` | Coupled CV-specific tokens with PDF-specific decisions. | Layered `CvTheme` + render-time `pageBackgrounds(...)`. |
-| `templates.theme` + `templates.themes` (two near-identical packages) | Confusingly similar names: `theme` (singular) holds built-in theme objects (`WeeklyScheduleTheme`); `themes` (plural) holds v2 token records (`Spacing`, `Typography`). | Merge into one **singular** `templates.theme` (matching `document.theme` / `cv.v2.theme`). Deferred to 2.0 because these are public types — the package move is binary-incompatible and would fail the japicmp gate. |
+| PDF-specific chrome overloads on `BusinessTheme` | Coupled CV-specific tokens with PDF-specific decisions. | Layered `BrandTheme` + render-time `pageBackgrounds(...)`. |
+| `templates.theme` + `templates.themes` (two near-identical packages) | Confusingly similar names: `theme` (singular) holds built-in theme objects (`WeeklyScheduleTheme`); `themes` (plural) holds v2 token records (`Spacing`, `Typography`). | Merge into one **singular** `templates.theme` (matching `document.theme` / `core.theme`). Deferred to 2.0 because these are public types — the package move is binary-incompatible and would fail the japicmp gate. |
### Open questions for 2.0 (no decision yet)
diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/v2/components/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/v2/components/package-info.java
index 1c4a039bf..fd9d69fda 100644
--- a/src/main/java/com/demcha/compose/document/templates/coverletter/v2/components/package-info.java
+++ b/src/main/java/com/demcha/compose/document/templates/coverletter/v2/components/package-info.java
@@ -5,6 +5,6 @@
* is the letter analog of the CV {@code SectionDispatcher}: every
* letter preset delegates its greeting / paragraphs / closing to it so
* all letters share one reading rhythm and inline-markdown handling
- * (via the reused {@code cv.v2.components.RichParagraphRenderer}).
+ * (via the reused {@code core.text.RichParagraphRenderer}).
*/
package com.demcha.compose.document.templates.coverletter.v2.components;
diff --git a/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md b/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md
index 4ce07dbc9..740874530 100644
--- a/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md
+++ b/src/main/java/com/demcha/compose/document/templates/cv/v2/AUTHORS.md
@@ -72,14 +72,14 @@ but every recipe below works the same way for any persona.
You want `▶` instead of `•`, or numbered bullets, or em-dashes.
This is a **theme** change, not a renderer change. Build a custom
-`CvDecoration` and hand it to a fresh `CvTheme`:
+`Decoration` and hand it to a fresh `BrandTheme`:
```java
-CvTheme theme = new CvTheme(
- CvPalette.classic(),
- CvTypography.classic(),
- CvSpacing.classic(),
- new CvDecoration(
+BrandTheme theme = new BrandTheme(
+ Palette.classic(),
+ Typography.classic(),
+ Spacing.classic(),
+ new Decoration(
"▶ ", // bullet glyph
" ", // stacked-row second-line indent (same visual width as bullet)
" · " // contact-line separator
@@ -104,17 +104,17 @@ pick a wider bullet you'll likely want a wider stacked-indent too.
You want the same Boxed Sections look but in navy instead of grey.
```java
-CvPalette navy = new CvPalette(
+Palette navy = new Palette(
DocumentColor.rgb(15, 34, 80), // ink — primary text
DocumentColor.rgb(90, 110, 150), // muted — italic subtitles
DocumentColor.rgb(120, 140, 180), // rule — separator lines
DocumentColor.rgb(220, 230, 240)); // banner — pale fill behind titles
-CvTheme navyTheme = new CvTheme(
+BrandTheme navyTheme = new BrandTheme(
navy,
- CvTypography.classic(),
- CvSpacing.classic(),
- CvDecoration.classic());
+ Typography.classic(),
+ Spacing.classic(),
+ Decoration.classic());
DocumentTemplate template = BoxedSections.create(navyTheme);
```
@@ -128,7 +128,7 @@ Same shape — sub-record swap, keep the rest of the theme.
You want a sans-serif body or a tighter scale.
```java
-CvTypography compact = new CvTypography(
+Typography compact = new Typography(
FontName.INTER, FontName.INTER,
18.0, // headline (was 21.5)
7.8, // contact
@@ -139,11 +139,11 @@ CvTypography compact = new CvTypography(
7.8, // body
1.3); // line spacing (was 1.4)
-CvTheme compactTheme = new CvTheme(
- CvPalette.classic(),
+BrandTheme compactTheme = new BrandTheme(
+ Palette.classic(),
compact,
- CvSpacing.classic(),
- CvDecoration.classic());
+ Spacing.classic(),
+ Decoration.classic());
```
---
@@ -159,17 +159,17 @@ See `presets/MinimalUnderlined.java` for a worked example. The pattern:
public final class MyPreset {
public static DocumentTemplate create() {
- return create(CvTheme.boxedClassic());
+ return create(BrandTheme.boxedClassic());
}
- public static DocumentTemplate create(CvTheme theme) {
+ public static DocumentTemplate create(BrandTheme theme) {
Objects.requireNonNull(theme, "theme");
return new Template(theme);
}
private static final class Template implements DocumentTemplate {
- private final CvTheme theme;
- Template(CvTheme theme) { this.theme = theme; }
+ private final BrandTheme theme;
+ Template(BrandTheme theme) { this.theme = theme; }
@Override public String id() { return "my-preset"; }
@Override public String displayName() { return "My Preset"; }
@@ -244,7 +244,7 @@ public sealed interface CvSection
```java
public final class QuoteRenderer {
private QuoteRenderer() {}
- public static void render(SectionBuilder section, QuoteSection q, CvTheme theme) {
+ public static void render(SectionBuilder section, QuoteSection q, BrandTheme theme) {
// …compose the visual using ParagraphPrimitive + theme tokens…
}
}
@@ -314,7 +314,10 @@ sidebar content to flow inline with main.
## Widget cookbook — the LEGO bricks
When you build a preset, you compose your `compose()` method from
-**widgets** that live in
+**widgets**. The neutral header widgets (`Headline`, `Subheadline`,
+`ContactLine`, `Masthead`, `SvgGlyph`) live in
+`com.demcha.compose.document.templates.core.identity`; the CV-specific
+section widgets (`SectionHeader` and friends) live in
`com.demcha.compose.document.templates.cv.v2.widgets`. Each widget
captures one visual idea, with named variants per visual style.
@@ -350,7 +353,7 @@ as DSL plumbing. Below is the current catalog.
| `ContactLine.render(host, identity, theme, align, order)` | low-level: pick alignment + field order | — |
The separator glyph comes from
-`theme.decoration().contactSeparator()` — swap `CvDecoration` to
+`theme.decoration().contactSeparator()` — swap `Decoration` to
change ` | ` to ` · ` or anything else.
### `SectionHeader` — title above a section body
@@ -379,7 +382,7 @@ rather than burying it in the theme.
### Preset-specific options
-Most presets need only `create()` or `create(CvTheme)`. When a visual
+Most presets need only `create()` or `create(BrandTheme)`. When a visual
choice is structural, keep it scoped to that preset. `NordicClean`
does this with `NordicClean.Options`: authors can move the
skills/education rail to the right and override the accent colour,
@@ -388,7 +391,7 @@ or affecting other presets.
```java
NordicClean.create(
- CvTheme.nordicClean(),
+ BrandTheme.nordicClean(),
NordicClean.Options.builder()
.railSide(NordicClean.RailSide.RIGHT)
.accentColor(DocumentColor.rgb(40, 110, 120))
@@ -510,7 +513,7 @@ so future readers can navigate the same way:
- **Theme as parameter**, not as a static or instance field. Renderers
must work for any theme passed to them.
- **No magic numbers** in renderer code. Every literal that affects
- visuals goes into `CvSpacing`, `CvTypography`, or `CvDecoration`.
+ visuals goes into `Spacing`, `Typography`, or `Decoration`.
- **No instanceof on the data** outside `SectionDispatcher`. That class
is the single dispatch point.
- **JavaDoc the public surface.** Sub-records and section types get a
@@ -524,12 +527,12 @@ so future readers can navigate the same way:
behavior, write a new preset that composes them differently, or
add a new theme token if it's cosmetic.
- ❌ Read raw `DocumentColor.rgb(...)` literals in renderer code. Add
- them to `CvPalette` so a theme can swap them.
+ them to `Palette` so a theme can swap them.
- ❌ Use `instanceof` on `CvSection` outside `SectionDispatcher`.
The dispatcher is the only place that knows about variants.
- ❌ Add behavior to data records. Records are inert.
- ❌ Break the public v2 API. If you must change a signature, add the
- new one and mark the old `@Deprecated` — see `CvTheme`'s 3-arg
+ new one and mark the old `@Deprecated` — see `BrandTheme`'s 3-arg
constructor for the pattern.
---
@@ -538,8 +541,8 @@ so future readers can navigate the same way:
| You want to change… | Add a new… |
|---|---|
-| Colour / font / size | `CvPalette` / `CvTypography` (theme) |
-| Bullet / separator glyph | `CvDecoration` (theme) |
+| Colour / font / size | `Palette` / `Typography` (theme) |
+| Bullet / separator glyph | `Decoration` (theme) |
| Layout / page-flow / which renderers run | **preset** |
| The data shape itself (new section type) | `CvSection` permits + renderer + dispatch branch |