11# Authoring Presets — write your own visual style
22
3- You like the layered architecture, but the three shipped presets
4- (` BoxedSections ` , ` MinimalUnderlined ` , ` ModernProfessional ` ) don't
5- match the design you want. This doc walks you through writing a
6- new preset from scratch — ** without subclassing, without duplicating
7- rendering code** .
3+ You like the layered architecture, but the shipped presets
4+ (` BoxedSections ` , ` MinimalUnderlined ` , ` ModernProfessional ` ,
5+ ` CenteredHeadline ` ) don't match the design you want. This doc walks
6+ you through writing a new preset from scratch — ** without subclassing,
7+ without duplicating rendering code** .
88
99If you haven't read [ quickstart.md] ( quickstart.md ) and
1010[ using-templates.md] ( using-templates.md ) , do those first.
@@ -59,9 +59,9 @@ visual decision you can read like a recipe.
5959<a id =" the-widget-catalog " ></a >
6060## The widget catalog
6161
62- Today, three widget classes live in
63- ` com.demcha.compose.document.templates.cv.v2.widgets ` . Each has 2-3
64- named variants.
62+ Today, four widget classes live in
63+ ` com.demcha.compose.document.templates.cv.v2.widgets ` . Each has a
64+ small set of named variants.
6565
6666### ` Headline ` — top-of-document name
6767
@@ -71,12 +71,19 @@ named variants.
7171| ` Headline.rightAligned(host, name, theme) ` | Right-aligned plain bold (` Jane Doe ` ) |
7272| ` Headline.render(host, name, theme, align, spacedCaps) ` | Low-level — any (alignment, transform) combo |
7373
74+ ### ` Subheadline ` — secondary tagline under the name
75+
76+ | Variant | Visual |
77+ | ---| ---|
78+ | ` Subheadline.centeredSpacedCaps(host, text, style) ` | Centred letter-spaced uppercase tagline (` P R O F E S S I O N A L T I T L E ` ) |
79+
7480### ` ContactLine ` — phone / email / address / links row
7581
7682| Variant | Visual |
7783| ---| ---|
7884| ` ContactLine.centered(host, identity, theme) ` | Centred, phone → email → address → links |
7985| ` ContactLine.rightAligned(host, identity, theme) ` | Right-aligned, address → phone → email → links |
86+ | ` ContactLine.twoRowRightAligned(host, identity, theme, bodyStyle, linkStyle, separatorStyle) ` | Right-aligned address/phone row plus email/link row |
8087| ` ContactLine.render(host, identity, theme, align, order) ` | Low-level — any alignment + field-order combo |
8188
8289### ` SectionHeader ` — title above each section body
@@ -86,6 +93,7 @@ named variants.
8693| ` SectionHeader.banner(host, title, theme) ` | Pale-grey panel + centred spaced-caps inside |
8794| ` SectionHeader.underlined(host, title, theme) ` | Small left spaced-caps + thin rule below |
8895| ` SectionHeader.flat(host, title, color, theme) ` | Large bold title in a given colour, no panel |
96+ | ` SectionHeader.flatSpacedCaps(host, title, color, theme, titleStyle) ` | Small left spaced-caps title in a soft colour, no panel |
8997
9098The separator glyph used by ` ContactLine ` , the bullet glyph used by
9199` RowRenderer ` , and other character-level choices come from
@@ -303,9 +311,10 @@ When you do add a new widget:
303311
3043121 . ** One file per widget** in ` cv/v2/widgets/ ` .
3053132 . ** ` public final class ` ** with a private constructor.
306- 3 . ** 2 -3 named factories** + a lower-level ` .render(...) ` .
314+ 3 . ** 1 -3 named factories** + a lower-level ` .render(...) ` when useful .
3073154 . ** First parameter is always ` SectionBuilder host ` ** .
308- 5 . ** Last parameter is always ` CvTheme theme ` ** .
316+ 5 . ** Pass ` CvTheme theme ` when the widget reads shared tokens** ;
317+ pass an explicit style only when the preset owns that unique style.
3093186 . ** No instance state** — all static, all stateless.
3103197 . ** JavaDoc the visual** — what does this look like? Who uses it?
3113208 . ** Add to ` WidgetSmokeTest ` ** with a basic "renders without
0 commit comments