Problem:
The PDF actions (app/data/action/create_pdf.py, app/data/action/edit_pdf.py) carry their own hardcoded styling - a private _THEMES dict with five baked-in palettes (default/corporate/minimal/warm/forest), Helvetica/Courier fonts, fixed heading sizes, banner heights, and margins. Meanwhile FORMAT.md already defines the canonical styling standard (colors, typography table, layout rules) under its ## global and ## pdf sections, and the agent is told to read it before generating any file. The result is two sources of truth: PDFs ignore the user-editable FORMAT.md and render off-brand, while every other format honours it. Users who customize FORMAT.md see no effect on PDF output.
Proposal:
Generalise the PDF actions so their styling derives from FORMAT.md instead of the inline _THEMES constant:
- Parse the
## global (colors, typography, layout) and ## pdf (page setup, design, structure) sections and map them onto the fpdf2 render pipeline - banner/header colors, body/heading sizes & weights, accent/highlight color, margins, footer.
- Keep a single CraftBot-brand default (base
#141517, highlight #FF4F18, Roboto) sourced from FORMAT.md rather than five divergent themes.
- Apply the same resolved style to both
create_pdf and edit_pdf so edits match the original document.
- Fall back to sane built-in defaults if FORMAT.md is missing or a key can't be parsed.
Out of scope:
- Changing the FORMAT.md schema/format itself.
- Touching non-PDF actions (docx/pptx/xlsx) - they can adopt the same pattern in follow-ups.
- Full font embedding/Roboto support (the latin-1 sanitizer stays as-is) unless trivial.
Acceptance:
create_pdf/edit_pdf produce PDFs whose colors, fonts, headings, margins, and footer match FORMAT.md's ## global/## pdf sections.
- Editing FORMAT.md (e.g. changing the highlight color) visibly changes subsequent PDF output with no code change.
- The hardcoded
_THEMES dict is removed (or reduced to a FORMAT.md-derived fallback).
- A missing/malformed FORMAT.md still renders a valid PDF via defaults.
- Existing
test_payload / diagnostic still passes; ruff format + ruff check clean.
Labels: feature, refactor, p2
Problem:
The PDF actions (
app/data/action/create_pdf.py,app/data/action/edit_pdf.py) carry their own hardcoded styling - a private_THEMESdict with five baked-in palettes (default/corporate/minimal/warm/forest), Helvetica/Courier fonts, fixed heading sizes, banner heights, and margins. MeanwhileFORMAT.mdalready defines the canonical styling standard (colors, typography table, layout rules) under its## globaland## pdfsections, and the agent is told to read it before generating any file. The result is two sources of truth: PDFs ignore the user-editable FORMAT.md and render off-brand, while every other format honours it. Users who customize FORMAT.md see no effect on PDF output.Proposal:
Generalise the PDF actions so their styling derives from
FORMAT.mdinstead of the inline_THEMESconstant:## global(colors, typography, layout) and## pdf(page setup, design, structure) sections and map them onto the fpdf2 render pipeline - banner/header colors, body/heading sizes & weights, accent/highlight color, margins, footer.#141517, highlight#FF4F18, Roboto) sourced from FORMAT.md rather than five divergent themes.create_pdfandedit_pdfso edits match the original document.Out of scope:
Acceptance:
create_pdf/edit_pdfproduce PDFs whose colors, fonts, headings, margins, and footer match FORMAT.md's## global/## pdfsections._THEMESdict is removed (or reduced to a FORMAT.md-derived fallback).test_payload/ diagnostic still passes;ruff format+ruff checkclean.Labels:
feature,refactor,p2