eliasoulkadi/shokunin/kagen

Claude Code and agent skill by eliasoulkadi/shokunin

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Convert Kami HTML templates to production-grade PDF via Chromium/Playwright. Complements Kami (design) with PDF rendering. Use when user asks to generate PDF files, render HTML to PDF, or export documents.

Install

npx vskill@latest install eliasoulkadi/shokunin/kagen

SKILL.md

kagen · 紙源

紙源 · かげん - paper source. PDF generation companion to Kami.

Kami designs, Kagen ships. Converts Kami HTML templates to production-grade PDF using Chromium (Playwright), bypassing WeasyPrint's Windows limitations.

Why Kagen

ProblemSolution
WeasyPrint doesn't work on Windows (no GTK)Kagen uses Playwright/Chromium — works everywhere
WeasyPrint cold-start ~630ms per renderPlaywright warm ~13ms per render
WeasyPrint can't execute JSChromium renders fully (charts, dynamic content)
wkhtmltopdf is deprecated and unmaintainedPlaywright is actively maintained by Microsoft

Based on benchmarks (pdf4.dev 2026), engineering discussions (HN, Stack Overflow, BrowserStack), and production experience from DocRaptor, customjs.space, and print-css.rocks.

Prerequisites

  • Node.js 20+
  • Playwright (npx playwright auto-installs on first use)
  • Chromium browser installed (npx playwright install chromium)
  • Kami HTML templates (any valid HTML with print CSS)

Quick start

powershell
npx playwright pdf "file:///path/to/doc.html" "output.pdf"

Or from Node.js:

js
const { chromium } = require('playwright');
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('file:///path/to/doc.html', { waitUntil: 'networkidle' });
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true,
margin: { top: '0', bottom: '0', left: '0', right: '0' }
});
await browser.close();

Production settings (from professional research)

Page options
js
await page.pdf({
path: 'output.pdf',
format: 'A4', // or 'Letter', 'A3'
printBackground: true, // always true — renders parchment bg
margin: { top: '0', bottom: '0', left: '0', right: '0' },
// For screen media (not print):
// await page.emulateMedia({ media: 'screen' });
});
Critical CSS rules for reliable PDF output
css
/* Always include in your HTML template header */
@page {
size: A4;
margin: 24mm 26mm 26mm 26mm;
background: #f5f4ed;
widows: 4;
orphans: 4;
}
/* Force background colors in Chromium */
* {
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
/* Avoid orphan text lines — high widows/orphans prevents single-line splits */
body { widows: 4; orphans: 4; }
p { widows: 3; orphans: 3; }
li { widows: 2; orphans: 2; }
/* Page break control — only on chapters with heavy content */
.chapter { }
.chapter.break { break-before: page; }
/* Never let a heading sit alone at page bottom */
h1, h2, h3, h4 { break-after: avoid; }
/* Keep these blocks intact — never split across pages */
table, pre, figure, .callout, .card,
blockquote, .finding-header, .takeaway {
break-inside: avoid;
}
/* Avoid code blocks getting orphaned from their preceding paragraph */
pre {
margin-top: 6pt;
page-break-before: avoid;
}
/* Tables should not break rows across pages */
table tr {
break-inside: avoid;
}
Visual patterns by document type

Each document type needs its own set of visual patterns. Apply accordingly:

TypeRequired patternsOptional patterns
Pentest / Security reportSeverity badges (red/orange/green), risk bar, code blocks with left border, impact/remediation boxesFinding-header with metadata, findings table with badges
One-pager / Executive summaryGlance grid (4 metrics), lead paragraph, takeaway box, cover with large title + decorative lineCallout for key data point, footer with contact
White paper / Long docChapter breaks in dense sections, table of contents, callouts, keep-together on critical blocksQuotes, diagrams, appendix
LetterWide margins (25mm), formal greeting and closing, no columns, no tablesLetterhead, signature
ResumeDense body (9.2pt), metric row, project bullets with action + resultTimeline, skills grid
SlidesAssertion-evidence titles, one idea per slide, one-line bullets, pinned calloutCode cards, 2x2 table

Rule: if the document type isn't in the table, choose the closest one and adapt.

Near-empty pages prevention

Nothing looks more amateur than a page with 2 lines. Causes and solutions:

CauseSolutionAuto-detection
Heading with 1 short paragraph at the endMerge with previous sectionIf a chapter has only 1 h2 + 1 p, it doesn't deserve its own page
break-before: page on every sectionOnly use on chapters with >1/3 page of contentCount paragraphs + tables + lists. If they add up to less than 5 elements, don't force a break
break-inside: avoid on large block that doesn't fitRelax break-inside or split the blockIf a keep-together measures more than 1 page, don't force it
Source list at the end spilling onto a separate pageMove to consolidated sources chapterSources go in one place, not repeated in each chapter
AI anti-patterns in documents

Validate that content inherited from Kami doesn't have these marks:

Anti-patternProblemFix
Repeated em dash — as label/value separatorBlack Box — no credentials, multiple lines in a rowParentheses, comma, colon. The dash is for genuine asides, not for separating labels
Uniform tables without colorAll rows identical, no visual indication of severity or priorityColor badges, subtle zebra rows, highlighted first column
Code blocks without contrastThey blend with the body, don't look like codeLeft blue border, ivory background, monospace, generous padding
Same structure on every pageEvery page is title + table or title + listVary: finding box, risk bar, flowchart, callout. Alternate rhythm
Claims without source"LLMs hallucinate 15-20%" without attribution"According to Vectara HHEM 2026, LLMs..."
Best practices from professionals
PracticeSourceWhy
Always set printBackground: trueBrowserStack, Playwright docsKami uses parchment bg #f5f4ed — Chromium strips it by default
Use file:// protocolStack Overflow, DocuPotionAvoids auth/CORS issues with local files
Set waitUntil: 'networkidle'BrowserStackEnsures fonts, CSS fully loaded
Lock browser version in CIBrowserStack, blog.rasc.chChromium updates can change rendering
Use @page margins, not Playwright marginsprint-css.rocks, CSS Paged Media specCSS margins are more predictable for paged media
-webkit-print-color-adjust: exactMDN, Chromium docsCritical for parchment backgrounds and brand colors
Reuse browser instance (warm)pdf4.dev benchmark42ms → 3ms speedup (14x)
Validate PDF visually in CIBrowserStackPage count, whitespace, font check

Warm mode (production pipeline)

js
const { chromium } = require('playwright');
class PDFRenderer {
constructor() {
this.browser = null;
}
async start() {
this.browser = await chromium.launch();
}
async render(htmlPath, outputPath) {
const page = await this.browser.newPage();
await page.goto('file:///' + htmlPath.replace(/\\/g, '/'), {
waitUntil: 'networkidle'
});
await page.pdf({
path: outputPath,
format: 'A4',
printBackground: true,
margin: { top: '0', bottom: '0', left: '0', right: '0' }
});
await page.close();
}
async stop() {
await this.browser.close();
}
}

Font embedding

Chromium embeds system fonts by default. For custom fonts (like TsangerJinKai02 in Kami):

css
@font-face {
font-family: "CustomFont";
src: url("fonts/CustomFont.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}

Place font files relative to the HTML and use relative src paths. Chromium resolves them from the HTML file's directory.

Troubleshooting

ProblemFix
White background instead of parchmentAdd printColorAdjust: exact in CSS and printBackground: true in JS
Fonts not renderingUse relative paths in @font-face, check font file exists
Page breaks wrongCheck break-inside: avoid on tables, pre, callout
Near-empty page (2 lines alone)Merge short section with previous; avoid break-before: page on light chapters
Content overflowUse page-break-inside: avoid on large blocks
Chinese chars as boxesInclude CJK font in @font-face or use system CJK fallback
PDF too largeRemove unnecessary images, compress embedded fonts
Slow first renderKeep browser instance alive (warm mode)
CSS visual pattern snippets

Concrete patterns to include in the HTML by document type:

css
/* Severity badges (pentest, security) */
.badge-high { background: #f5e8e8; color: #a83030; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }
.badge-medium { background: #f5ede2; color: #b86a25; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }
.badge-ok { background: #e8f2ec; color: #2a7a4a; display: inline-block; padding: 2pt 7pt; border-radius: 3pt; font-size: 8pt; font-weight: 500; text-transform: uppercase; }
/* Risk bar (pentest exec summary) */
.risk-bar { display: flex; gap: 2pt; margin: 8pt 0 14pt 0; height: 12pt; }
.risk-bar .seg { border-radius: 2pt; display: flex; align-items: center; justify-content: center; font-size: 7pt; color: #fff; font-weight: 500; }
/* Code blocks with left border (pentest, technical) */
pre { border-left: 2.5pt solid #1B365D; border-radius: 3pt; background: #faf9f5; padding: 10pt 14pt; font-family: Consolas, monospace; font-size: 9pt; line-height: 1.5; break-inside: avoid; }
/* Impact/Remediation boxes (pentest) */
.impact-box, .remediation-box { border-left: 2pt solid #e8e6dc; padding-left: 12pt; margin: 10pt 0 14pt 0; break-inside: avoid; }
.impact-box .label, .remediation-box .label { font-size: 8.5pt; letter-spacing: 0.8pt; text-transform: uppercase; font-weight: 500; color: #1B365D; margin-bottom: 4pt; }
/* Cover accent line */
.cover-line { width: 60pt; height: 2pt; background: #1B365D; margin: 20pt 0; border-radius: 1pt; }
/* Pipeline flow (4 step horizontal) */
.pipeline-flow { display: flex; gap: 0; margin: 18pt 0; break-inside: avoid; }
.pipeline-step { flex: 1; text-align: center; padding: 10pt 8pt; }
.pipeline-step .dot { width: 6pt; height: 6pt; border-radius: 50%; background: #1B365D; margin: 0 auto 5pt auto; }
.pipeline-step + .pipeline-step { border-left: 0.5pt dotted #e8e6dc; }
.pipeline-step .name { font-size: 9pt; font-weight: 500; color: #141413; margin-bottom: 3pt; }
.pipeline-step .desc { font-size: 7.5pt; color: #6b6a64; line-height: 1.35; }
/* Keep-together wrapper */
.keep-together { break-inside: avoid; }
Self-review protocol (mandatory)

Don't generate the PDF without passing this checklist. Each item is a real failure documented in previous iterations.

Structural (blocking)
  • [ ] Each chapter has enough content to fill >1/3 of a page
  • [ ] No sections with just heading + 1 short paragraph (merge)
  • [ ] No near-empty pages (2 lines alone)
  • [ ] break-before: page only on chapters with dense content
Visual (high priority)
  • [ ] Visual elements match the document type (badges, risk bars, code blocks, etc.)
  • [ ] Tables have proper styling (optional zebra, padding, clear headers)
  • [ ] Code blocks are distinguishable from body (border, background, monospace)
  • [ ] No repeated em dashes — used as label/value separators
  • [ ] There's variety in visual rhythm (not all pages the same)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
91
Repository forks
10
7-day trend score
23

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/eliasoulkadi/shokunin/kagen/badge)](https://verified-skill.com/skills/eliasoulkadi/shokunin/kagen)

Something wrong with this skill or its page? Tell us.