v0.7.0 - brand appearance, model-driven color, cover & caption-index fidelity
[0.7.0] - 2026-06-09
Brand-fidelity release: the engine now follows a template's real per-run typography
(font, size, color), applies model-named brand colors, fills content-control covers
faithfully, and regenerates caption indexes from the new content. Schema stays 1.2.0
(additive); profiles from earlier versions keep working unchanged.
Added
- Brand typography capture (font family + size + color). Extraction now captures
the template's dominant DIRECT run typography - the real visible font, font size
and run color a designed template applies per-run (e.g. Roboto 16pt) rather than
via the named styles or theme - into the reservedrole.appearancefield and the
additivetheme.fonts.body(font/size) andtheme.text.body(color). Generation
applies all three as direct run formatting through the resolver (paragraphs, list
items, captions, quotes, callouts, table cells, and hyperlink runs), so a generated
document renders in the template's real font, size and color instead of falling
back to thedocDefaults(typically Arial 11pt black)._extract_themealso reads
the realtheme1.xmlmajor/minor fonts anddocDefaults.- Universal and deterministic. Each axis is captured by dominant sampling over
ALL runs (a run with no explicit value votes "inherit"), so a value is applied
only when it dominates the whole document - an accent color present on a few runs
never becomes the body color. Nothing is hardcoded to any template; a document
with no dominant value (and every pre-capture profile) behaves exactly as before. - Brand guarantee, fail-closed. Every applied font/size/color is re-validated
against what the shell proves it contains (appearance_targets_exist): fonts vs
the fontTable + theme, sizes vs the template's ownw:szvalues, colors vs the
theme palette + the template's ownw:colorvalues. The body size/color default
never flows onto heading roles (their style's intrinsic size/color is preserved). - Deferred (see ROADMAP section 1): per-word accents,
cover-layout reconstruction, and heading typography when the template fakes
headings in the body style.
- Universal and deterministic. Each axis is captured by dominant sampling over
- Model-driven brand color (run color palette tokens). The profile now carries a
theme.paletteof the template's brand colors (theme slots likeaccent1, plus
off-themehex:RRGGBB) with usage provenance; an IntermediateDocument run can carry
a semanticcolortoken (a palette key, never a literal hex) that the resolver maps
to the brand color and the generator applies - rendering a theme color as
w:color@w:val=<hex>+w:themeColor=<slot>so it shows in both LibreOffice and
Word. The model NAMES each color's purpose viacomprehension.palette_annotations;
it never authors a color (fail-closed: a token into an empty/absent palette errors). - Caption-index regeneration (list of tables / figures). A kept caption index
(TOC \c "<seq>") is now repopulated from the new content: each captioned table or
figure emits a real WordSEQfield, and the index's visible cache is rebuilt from
the emitted captions (so a headless render shows the new entries, not the template's
stale ones). The model maps a caption kind to its index via the new closed
comprehension.conventions.indexes[*].caption_target(table|figure); brand- and
language-agnostic (the seq label is the template's own, read from the profile). - Cover fidelity for content-control covers. A cover content control bound to a
core property (e.g. the subject repeated in the page header) now has its cached run
text refreshed across the body and every header/footer, so a headless render shows
the filled value, not the template prompt. The cover role-style re-assertion is
gated to bare placeholder controls, so a real author-formatted slot keeps its own
formatting (a builtinSubtitlewhose color is a near-white tint no longer blanks a
filled cover subtitle).
Fixed
- Colored hyperlink runs now write
w:colorat the schema-correctCT_RPrposition
(beforew:u/w:sz/w:vertAlign) instead of appending it last, so an
underlined colored link is conformant OOXML; a theme-token link with no resolved hex
emitsthemeColoronly (no strayw:val="000000"that would paint it black).