
Payslip — rendered output
npx @formepdf/html templates/payslip/index.html -o payslip.pdf
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Statement of earnings — Northmoor Industrial Group, Inc.</title>
<link rel="stylesheet" href="../northmoor-shared.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="sheet">
<div class="atop"></div>
<div class="pagefill">
<header>
<div class="hd">
<div class="mast-left">
<div class="mark">N</div>
<div>
<div class="wm">Northmoor</div>
<div class="sub" style="margin-top: 3pt">Payroll — Confidential</div>
</div>
</div>
<div class="addr" style="text-align: right">418 Ellingham Road, Suite 300<br>Rochester, NY 14604<br>EIN 16-1904472</div>
</div>
<div class="hr2 mast-divider"></div>
<div class="dochead">
<div>
<div class="lbl lbl-accent" style="margin-bottom: 7.5pt">Payroll · confidential</div>
<h1 class="dtitle">Statement of earnings</h1>
</div>
<div style="text-align: right">
<div class="lbl" style="margin-bottom: 5.25pt">Pay date</div>
<div class="refnum">04 September 2026</div>
</div>
</div>
</header>
<div class="meta meta-doc">
<div><div class="lbl">Employee</div>Marcus L. Vance<br>1174 Bellwood Terrace<br>Rochester, NY 14618</div>
<div><div class="lbl">Employee no.</div>18822<div class="lbl meta-gap">Department</div>4200 · Fabrication</div>
<div><div class="lbl">Pay period</div>16–31 August 2026<div class="lbl meta-gap">Frequency</div>Semi-monthly</div>
<div><div class="lbl">Filing status</div>Single · NY resident<div class="lbl meta-gap">Allowances</div>0 · no additional withholding</div>
</div>
<div class="cols">
<div class="earncol">
<h2 class="lbl lbl-table">Earnings</h2>
<table class="t">
<thead>
<tr>
<th scope="col">Description</th>
<th scope="col" class="num" style="width: 39pt">Hours</th>
<th scope="col" class="num" style="width: 43.5pt">Rate</th>
<th scope="col" class="num" style="width: 58.5pt">Current</th>
<th scope="col" class="num" style="width: 66pt">Year to date</th>
</tr>
</thead>
<tbody>
<tr><td>Regular salary</td><td class="num">86.67</td><td class="num">34.62</td><td class="num">3,000.00</td><td class="num">51,000.00</td></tr>
<tr><td>Overtime, 1.5×</td><td class="num">6.50</td><td class="num">51.93</td><td class="num">337.55</td><td class="num">5,742.35</td></tr>
<tr><td>Shift differential</td><td class="num">—</td><td class="num">—</td><td class="num">45.00</td><td class="num">760.00</td></tr>
<tr class="gsub"><td>Gross pay</td><td class="num">93.17</td><td class="num"></td><td class="num">3,382.55</td><td class="num">57,502.35</td></tr>
</tbody>
</table>
</div>
<div class="dedcol">
<h2 class="lbl lbl-table">Deductions</h2>
<table class="t">
<thead>
<tr>
<th scope="col">Description</th>
<th scope="col" class="num" style="width: 58.5pt">Current</th>
<th scope="col" class="num" style="width: 66pt">Year to date</th>
</tr>
</thead>
<tbody>
<tr><td>Federal income tax</td><td class="num">421.60</td><td class="num">7,167.20</td></tr>
<tr><td>Social security, 6.20%</td><td class="num">209.72</td><td class="num">3,565.15</td></tr>
<tr><td>Medicare, 1.45%</td><td class="num">49.05</td><td class="num">833.78</td></tr>
<tr><td>New York state tax</td><td class="num">158.34</td><td class="num">2,691.78</td></tr>
<tr><td>Medical, pre-tax</td><td class="num">142.50</td><td class="num">2,422.50</td></tr>
<tr><td>401(k), 5.00%</td><td class="num">169.13</td><td class="num">2,874.37</td></tr>
<tr class="gsub"><td>Total deductions</td><td class="num">1,150.34</td><td class="num">19,554.78</td></tr>
</tbody>
</table>
</div>
</div>
<div class="cols2">
<div class="leavecol">
<h2 class="lbl lbl-table">Leave balances</h2>
<table class="t mini">
<thead>
<tr>
<th scope="col">Plan</th>
<th scope="col" class="num">Accrued</th>
<th scope="col" class="num">Taken</th>
<th scope="col" class="num">Available</th>
</tr>
</thead>
<tbody>
<tr><td>Vacation</td><td class="num">106.67</td><td class="num">64.00</td><td class="num">42.67</td></tr>
<tr><td>Sick</td><td class="num">40.00</td><td class="num">16.00</td><td class="num">24.00</td></tr>
<tr><td>Personal</td><td class="num">16.00</td><td class="num">8.00</td><td class="num">8.00</td></tr>
</tbody>
</table>
</div>
<div class="netcol">
<table class="tt tt-flush">
<tbody>
<tr><td>Gross pay</td><td class="num">3,382.55</td></tr>
<tr><td>Total deductions</td><td class="num">(1,150.34)</td></tr>
<tr class="total"><td>Net pay — direct deposit</td><td class="num">2,232.21</td></tr>
</tbody>
</table>
<div class="deposit">Deposited to account ending 3391 · First Genesee Bank<br>Year to date net pay 37,947.57</div>
</div>
</div>
<div class="pagefill-spacer"></div>
<footer class="foot">
<div style="flex-grow: 1"><div class="lbl">Employer contributions, not deducted from pay</div>Medical 486.00 · 401(k) match, 3% 101.48 · Social security and Medicare 258.77 · State unemployment 34.16</div>
<div style="flex-grow: 1"><div class="lbl">Queries</div>Payroll, (585) 274-0180 ext. 402. Keep this statement; it is required to support your annual tax return. Address changes must be filed on form F-04 before the period cut-off.</div>
</footer>
</div>
</div>
</body>
</html>
/* payslip — page geometry and document-specific rules.
* Spine comes from ../northmoor-shared.css. */
@page {
size: Letter;
margin: 52.5pt 57pt 40.5pt; /* 70px 76px 54px */
@bottom-left {
content: "Statement of earnings · M. L. Vance · Advice 2026-17";
font-family: Helvetica, Arial, sans-serif;
font-size: 5.625pt;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #8A857E;
}
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
font-family: Helvetica, Arial, sans-serif;
font-size: 5.625pt;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #8A857E;
}
}
/* First-page 4px full-bleed accent head rule (escapes into the margin). */
.sheet { position: relative; }
.atop {
position: absolute;
top: -52.5pt;
left: -57pt;
right: -57pt;
height: 3pt;
background-color: #7B2233;
}
.meta-doc { grid-template-columns: 1.2fr 1fr 1fr 1fr; }
.cols { display: flex; gap: 21pt; margin-top: 22.5pt; } /* 28px / 30px */
.cols2 { display: flex; gap: 21pt; margin-top: 19.5pt; align-items: flex-start; } /* 26px */
.lbl-table { margin-bottom: 7.5pt; }
.deposit { font-size: 6.375pt; color: #5A5A5A; margin-top: 6pt; text-align: right; }
/* Equal/ratio split columns: explicit widths (flex basis is not in
* the subset; grow alone leaves intrinsic-width columns). */
.cols > div.earncol { width: 53%; }
.cols > div.dedcol { width: 42%; }
.cols2 > div.leavecol { width: 53%; }
.cols2 > div.netcol { width: 42%; }
northmoor-shared.css alongside them — the set’s shared spine (type scale, tables, signature blocks, the accent).
Sample data (data.json)
Sample data (data.json)
data.json
{
"issuer": {
"name": "Northmoor Industrial Group, Inc.",
"address": "418 Ellingham Road, Suite 300, Rochester, NY 14604",
"phone": "(585) 274-0180",
"ein": "16-1904472",
"bank": {
"name": "First Genesee Bank, Rochester NY",
"account": "8841 002937",
"routing": "021304559"
}
},
"document": {
"type": "payslip",
"advice": "2026-17",
"payDate": "04 September 2026",
"period": "16–31 August 2026",
"frequency": "Semi-monthly"
},
"employee": {
"name": "Marcus L. Vance",
"address": "1174 Bellwood Terrace, Rochester, NY 14618",
"employeeNo": "18822",
"department": "4200 · Fabrication",
"filingStatus": "Single · NY resident",
"allowances": "0 · no additional withholding"
},
"earnings": [
{
"description": "Regular salary",
"hours": 86.67,
"rate": 34.62,
"current": 3000.0,
"ytd": 51000.0
},
{
"description": "Overtime, 1.5×",
"hours": 6.5,
"rate": 51.93,
"current": 337.55,
"ytd": 5742.35
},
{
"description": "Shift differential",
"hours": null,
"rate": null,
"current": 45.0,
"ytd": 760.0
}
],
"grossPay": {
"hours": 93.17,
"current": 3382.55,
"ytd": 57502.35
},
"deductions": [
{
"description": "Federal income tax",
"current": 421.6,
"ytd": 7167.2
},
{
"description": "Social security, 6.20%",
"current": 209.72,
"ytd": 3565.15
},
{
"description": "Medicare, 1.45%",
"current": 49.05,
"ytd": 833.78
},
{
"description": "New York state tax",
"current": 158.34,
"ytd": 2691.78
},
{
"description": "Medical, pre-tax",
"current": 142.5,
"ytd": 2422.5
},
{
"description": "401(k), 5.00%",
"current": 169.13,
"ytd": 2874.37
}
],
"totalDeductions": {
"current": 1150.34,
"ytd": 19554.78
},
"netPay": {
"current": 2232.21,
"ytdNet": 37947.57,
"depositAccount": "ending 3391 · First Genesee Bank"
},
"leave": [
{
"plan": "Vacation",
"accrued": 106.67,
"taken": 64.0,
"available": 42.67
},
{
"plan": "Sick",
"accrued": 40.0,
"taken": 16.0,
"available": 24.0
},
{
"plan": "Personal",
"accrued": 16.0,
"taken": 8.0,
"available": 8.0
}
],
"employerContributions": {
"medical": 486.0,
"match401k": 101.48,
"ssAndMedicare": 258.77,
"stateUnemployment": 34.16
}
}
MIT-licensed, free to copy — source on GitHub. Passes PDF/UA-1 validation (veraPDF) in CI; validation is a floor, not a certification.