pdf-design▌
jamditis/claude-skills-journalism · updated Apr 8, 2026
Create and edit professional PDF reports and funding proposals with live preview and iterative design.
PDF Design System
Create and edit professional PDF reports and funding proposals with live preview and iterative design.
Interactive editing mode
During a design session, use these commands:
| Command | Action |
|---|---|
preview |
Screenshot current state |
preview page N |
Screenshot specific page |
show cover |
Preview cover page |
show budget |
Preview budget section |
regenerate |
Create new PDF |
upload |
Upload to Google Drive |
done |
Finish session |
Workflow:
- You say "preview" → I show current state
- You describe changes → I implement them
- Repeat until done → Generate final PDF
Quick start
# Copy template to start new report
cp ~/.claude/plugins/pdf-design/templates/democracy-day-proposal.html ./new-report.html
# Generate PDF (must use snap-accessible path)
mkdir -p ~/snap/chromium/common/pdf-work
cp new-report.html ~/snap/chromium/common/pdf-work/
chromium-browser --headless --disable-gpu \
--print-to-pdf="$HOME/snap/chromium/common/pdf-work/output.pdf" \
--no-pdf-header-footer \
"file://$HOME/snap/chromium/common/pdf-work/new-report.html"
Document types
- Funding proposals — Grant requests with budgets
- Program reports — Initiative updates
- Impact reports — Metrics and outcomes
- Budget summaries — Financial breakdowns
Key principles
- Sentence case — Never Title Case
- Left-aligned — Never justified text
- Print-ready — 8.5" × 11" letter size
- Brand consistent — CCM red or program palettes
Brand guidelines
CCM standard colors
:root {
--ccm-red: #CA3553;
--ccm-black: #000000;
--ccm-gray: #666666;
--ccm-light: #e2e8f0;
}
Program-specific (Democracy Day)
:root {
--civic-navy: #1a2b4a;
--civic-blue: #2d4a7c;
--civic-gold: #c9a227;
--civic-red: #b31942;
}
Typography
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&family=Source+Sans+Pro:wght@300;400;600&display=swap" rel="stylesheet">
body {
font-family: 'Source Sans Pro', sans-serif;
font-size: 0.875rem;
line-height: 1.6;
}
h1, h2, h3 {
font-family: 'Montserrat', sans-serif;
}
HTML structure
Page setup
@page { size: letter; margin: 0; }
.page {
width: 8.5in;
height: 11in;
display: grid;
grid-template-rows: auto 1fr auto;
overflow: hidden;
page-break-after: always;
}
Cover page
<div class="page cover">
<div class="cover-header">
<div class="cover-org">Center for Cooperative Media</div>
<h1 class="cover-title">Report title</h1>
<p class="cover-intro">Brief description.</p>
</div>
<div class="cover-footer">
<div class="cover-stats"><!-- Stats --></div>
<div class="cover-footer-right">
<div class="cover-date">February 2026</div>
<div class="cover-logo"><img src="..." alt="Logo"></div>
</div>
</div>
</div>
Content page
<div class="page content-page">
<div class="page-header">
<div class="page-header-title">Document title</div>
<div class="page-number">2</div>
</div>
<div class="page-body">
<!-- Content goes here -->
</div>
<footer class="page-footer">
<!-- Footer -->
</footer>
</div>
Budget table
<table class="budget-table">
<thead>
<tr><th>Expense</th><th>Per year</th><th>Total</th></tr>
</thead>
<tbody>
<tr>
<td>Item<span class="item-desc">Details</span></td>
<td>$10,000</td>
<td>$20,000</td>
</tr>
</tbody>
<tfoot>
<tr><td>Total</td><td>$50,000</td><td>$100,000</td></tr>
</tfoot>
</table>
Page footer
.page-body {
padding: 0.2in 0.65in 0.3in;
overflow: hidden;
}
.page-footer {
padding: 0 0.65in 0.5in;
border-top: 1px solid #e2e8f0;
font-size: 0.8rem;
}
Footer clearance
Content must not touch or overlap the page footer. These rules apply to content pages — cover pages and special layouts may use different structures.
- Content pages must use
display: grid; grid-template-rows: auto 1fr autoon.page - Content pages must have exactly 3 direct children: header, content wrapper (
.page-body), footer - The content wrapper must have
overflow: hiddento prevent text bleeding - Never use
position: absolutefor footers — keep them in normal document flow as the third grid row - Use
.page-footer:empty { display: none; }so pages without footer content don't render a blank border - If content is too long, reduce content rather than shrinking the footer gap
PDF generation
Chromium (snap-confined)
# Must use ~/snap/chromium/common/ path
mkdir -p ~/snap/chromium/common/pdf-work
cp template.html ~/snap/chromium/common/pdf-work/
chromium-browser --headless --disable-gpu \
--print-to-pdf="$HOME/snap/chromium/common/pdf-work/output.pdf" \
--no-pdf-header-footer \
"file://$HOME/snap/chromium/common/pdf-work/template.html"
cp ~/snap/chromium/common/pdf-work/output.pdf ./
Preview pages
# PDF to PNG
pdftoppm -png -f 1 -l 1 output.pdf preview
# Page count
pdfinfo output.pdf | grep Pages
Legion browser preview
~/.claude/scripts/legion-browser.py screenshot "file:///path/to/template.html" -o preview.png
Google Drive upload
cd ~/.claude/workstation/mcp-servers/gmail && source .venv/bin/activate
python3 << 'PYEOF'
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.oauth2.credentials import Credentials
import json
with open('/home/jamditis/.claude/google/drive-token.json') as f:
token_data = json.load(f)
creds = Credentials(
token=token_data['access_token'],
refresh_token=token_data.get('refresh_token'),
token_uri='https://oauth2.googleapis.com/token',
client_id=token_data.get('client_id'),
client_secret=token_data.get('client_secret')
)
service = build('drive', 'v3', credentials=creds)
# Upload new file
file_metadata = {
'name': 'Report.pdf',
'parents': ['1lKTdwq4_5uErj-tBN112WCdJGD2YtetO'] # Shared with Joe
}
media = MediaFileUpload('/path/to/output.pdf', mimetype='application/pdf')
file = service.files().create(body=file_metadata, media_body=media, fields='id,webViewLink').execute()
print(f"Uploaded: {file.get('webViewLink')}")
PYEOF
Drive folders
- Shared with Joe:
1lKTdwq4_5uErj-tBN112WCdJGD2YtetO - Claude Workspace:
1e5dtKOiuvk0PPrFq3UyNI2UAa6RFiom3
Known issues
- Base64 images — Don't read HTML with large base64 using Read tool (API error). Use sed/grep/Python.
- Snap confinement — Chromium can only write to
~/snap/chromium/common/ - Fonts — Google Fonts via CDN; for offline, embed as base64
Logo locations
- CCM logo:
~/.claude/plugins/pdf-design/templates/(embedded in template) - Brand assets:
/home/jamditis/projects/cjs2026/public/internal/brand_web_assets/
Template
Reference: ~/.claude/plugins/pdf-design/templates/democracy-day-proposal.html
Discussion
Product Hunt–style comments (not star reviews)- No comments yet — start the thread.
Ratings
4.8★★★★★43 reviews- ★★★★★Amina Smith· Dec 16, 2024
pdf-design is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Amina Mensah· Dec 12, 2024
I recommend pdf-design for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
- ★★★★★Dhruvi Jain· Dec 8, 2024
Useful defaults in pdf-design — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Oshnikdeep· Nov 27, 2024
pdf-design is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
- ★★★★★Evelyn Nasser· Nov 19, 2024
Registry listing for pdf-design matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Rahul Santra· Nov 7, 2024
Registry listing for pdf-design matched our evaluation — installs cleanly and behaves as described in the markdown.
- ★★★★★Naina Reddy· Nov 7, 2024
Useful defaults in pdf-design — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
- ★★★★★Amina Garcia· Nov 3, 2024
Keeps context tight: pdf-design is the kind of skill you can hand to a new teammate without a long onboarding doc.
- ★★★★★Pratham Ware· Oct 26, 2024
pdf-design reduced setup friction for our internal harness; good balance of opinion and flexibility.
- ★★★★★Amina Rahman· Oct 26, 2024
I recommend pdf-design for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.
showing 1-10 of 43