Document design
Create professional, print-ready HTML documents that export to PDF with customizable branding.
Brand configuration
Before creating documents, check for pdf-playground.local.md in the project
root. If it is absent, check the legacy Claude Code path
.claude/pdf-playground.local.md. If both exist, use only the project-root
file. If neither exists, use sensible defaults or ask the user for their brand
colors.
Reading brand config
Parse the selected config file's YAML frontmatter:
yaml--- brand: name: "Organization Name" tagline: "Tagline" website: "https://example.com" email: "contact@example.com" colors: primary: "#CA3553" secondary: "#000000" background: "#FFFFFF" text: "#2d2a28" muted: "#666666" fonts: heading: "Playfair Display" body: "Source Sans 3" style: headingCase: "sentence" useOxfordComma: true ---
Default brand values
If no config exists, use these defaults:
- Primary color:
#CA3553(red) - Secondary color:
#000000(black) - Heading font: Playfair Display
- Body font: Source Sans 3
- Heading case: sentence case
Core principles
- Print-first design: All documents target 8.5" × 11" letter size with proper margins
- Brand compliance: Use colors and fonts from brand configuration
- Sentence case by default: Unless brand config specifies "title" case
- Clean exports: Documents must render correctly when printed to PDF
CSS variables
Generate CSS variables from brand config:
css:root { --primary: [colors.primary]; --secondary: [colors.secondary]; --background: [colors.background]; --text: [colors.text]; --muted: [colors.muted]; /* Derived colors */ --primary-dark: [darken primary by 15%]; --gray-100: #f5f4f2; --gray-200: #e8e6e3; }
Print CSS fundamentals
Page setup
css@page { size: 8.5in 11in; margin: 0; } @media print { body { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } .page { page-break-after: always; page-break-inside: avoid; } }
Fixed page dimensions
css.page { width: 8.5in; height: 11in; padding: 0.5in 0.75in; padding-bottom: 1in; /* Space for footer */ position: relative; box-sizing: border-box; overflow: hidden; }
Fixed footers
css.page-footer { position: absolute; bottom: 0.4in; left: 0.75in; right: 0.75in; font-size: 9pt; border-top: 1px solid var(--gray-200); padding-top: 0.1in; background: var(--background); }
Footer clearance (critical)
Content overlapping or touching the footer is a recurring issue.
Preferred layout, grid rows auto 1fr auto:
css.page { display: grid; grid-template-rows: auto 1fr auto; overflow: hidden; }
This makes the header and footer take their natural height, and the content fills the remaining space. No magic-number calc() needed, the footer clearance is structural.
Required safeguards:
- Use
grid-template-rows: auto 1fr autoon the page so content automatically gets the space between header and footer - Set
overflow: hiddenon the content container to prevent text bleeding past its bounds - Include
padding-bottom: 0.3in(minimum) inside the content area as a buffer - Never use hardcoded
height: calc(...)with magic numbers for header/footer heights, they drift when padding or font sizes change - After rendering, always screenshot and visually verify the bottom of the page before delivering
- If content overflows, reduce content, never shrink the footer gap. Tighten the header first if you need more room.
Typography patterns
Font loading
css@import url('https://fonts.googleapis.com/css2?family=[heading-font]:wght@400;600;700&family=[body-font]:wght@400;500;600;700&display=swap'); body { font-family: '[body-font]', Arial, sans-serif; font-size: 11pt; line-height: 1.6; color: var(--text); } h1, h2, h3 { font-family: '[heading-font]', Georgia, serif; font-weight: 700; }
Heading styles
css.section-title { font-size: 26pt; color: var(--secondary); margin-bottom: 0.25in; } .section-title::after { content: ''; display: block; width: 0.5in; height: 3px; background: var(--primary); margin-top: 0.12in; }
Common components
Cover page header
html<header class="cover-header"> <div class="logo-bar"> <div class="logo-primary">[brand.name]</div> </div> <div class="cover-title-block"> <div class="cover-eyebrow">[Document type] • [Date]</div> <h1 class="cover-title">[Title in configured case]</h1> </div> </header>
Budget table
css.budget-table thead { background: var(--secondary); color: white; } .budget-table tbody tr:last-child { background: var(--primary); color: white; font-weight: 700; }
Highlight box
css.highlight-box { background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%); color: white; padding: 0.3in; }
Document creation workflow
- Check for brand config at project-root
pdf-playground.local.md, then the legacy.claude/pdf-playground.local.mdfallback - Locate this installed
SKILL.mdand resolve bundled resources from its directory. Do not assume a plugin-root environment variable is available. - Load template from the skill-relative
templates/directory - Apply brand settings to CSS variables and content
- Customize content based on user requirements
- Save HTML file in current working directory
- Offer preview with Playwright browser tools
PDF export instructions
- Open the HTML file in Chrome
- Press Ctrl+P (or Cmd+P on Mac)
- Set "Destination" to "Save as PDF"
- Set "Margins" to "None"
- Enable "Background graphics"
- Save the file
Additional resources
Templates
Pre-built templates in the installed skill's templates/ directory:
proposal-template.htmlreport-template.htmlonepager-template.htmlnewsletter-template.htmlslides-template.htmlevent-template.html
slides-template.html contains illustrative local photo and wordmark paths,
not bundled image assets. Before delivering a deck based on it, replace every
CSS url(...) and <img src> reference with an available asset. If the user
has no suitable images, remove every unresolved reference, use the template's
gradient or solid-color slide variants, and replace a missing wordmark image
with text. Never deliver a deck with an unresolved local asset path.
Brand examples
Example brand configurations in the installed skill's brands/ directory:
default.yaml- Default brand settingsccm.yaml- Center for Cooperative Mediaexample-newsroom.yaml- Sample newsroom config
Reference files
For detailed CSS patterns, use the installed skill's
references/css-patterns.md.
Preview controls
Reusable preview assets are in the installed skill's controls/ directory.
These files are resources for document generation; they do not turn the
Claude-only preview command or plugin hook into Codex features.

