The pdg book · Chapter 10 of 10 · Putting it together
Build a real page
A complete invoice, assembled step by step from everything in the book — then a CSS-to-pdg cheat sheet and where to go next.
Everything in this book has been one idea at a time. Let's spend the last chapter combining them into something you would actually send: a one-page invoice. We will build it in layers, then look at the whole thing.
Layer 1: the header
Start with the masthead — a company name and an invoice number, pushed to opposite
ends with the <expander> spring, sitting on a dark
band.
<horizontal main="space-between" cross="center"
style:padding="14px 16px" style:background="#1b1a17">
<text size="20" bold="true" color="#faf6ed">Acme & Co.</text>
<vertical cross="end">
<text size="11" color="#9a948a">INVOICE</text>
<text size="14" bold="true" color="#faf6ed">#0042</text>
</vertical>
</horizontal>Layer 2: the bill-to block
Two columns of details, balanced with flex so they share the width evenly — the
flexbox lesson from Chapter 5.
<horizontal gap="20px" style:padding="14px 0">
<vertical flex="1" gap="2px">
<text size="9" bold="true" color="#847d6c">BILL TO</text>
<text size="12" bold="true">Wile E. Coyote</text>
<text size="11" color="#3c392f">Desert Route 1, Arizona</text>
</vertical>
<vertical flex="1" cross="end" gap="2px">
<text size="9" bold="true" color="#847d6c">DATE</text>
<text size="12">15 June 2026</text>
<text size="11" color="#3c392f">Due in 30 days</text>
</vertical>
</horizontal>Layer 3: the line items
The heart of the invoice is a <table>: a fixed-width
description column that flexes, and right-aligned numeric columns.
<table columns="1* 70px 80px" cell-padding="7px"
border="0.6px #ddd5c4 rows outer" stripe="#faf6ed">
<header>
<row background="#1b1a17" color="#ffffff">
<cell bold="true">Description</cell>
<cell bold="true" align="right">Qty</cell>
<cell bold="true" align="right">Amount</cell>
</row>
</header>
<row>
<cell>Rocket-powered roller skates</cell>
<cell align="right">2</cell>
<cell align="right">$240.00</cell>
</row>
<row>
<cell>Giant rubber band, industrial</cell>
<cell align="right">1</cell>
<cell align="right">$ 75.00</cell>
</row>
<row>
<cell bold="true">Total</cell>
<cell />
<cell bold="true" align="right">$315.00</cell>
</row>
</table>Layer 4: a closing note
A padded, rounded callout. keep="true" pins it together so it can never straddle
a page break — the keep-together rule from Chapter 9.
<text size="11" color="#3c392f" keep="true"
style:padding="12px" style:background="#faf6ed"
style:border-radius="8px">
Thank you for your business. Payment is due within 30 days; please reference
invoice <b>#0042</b> on your transfer.
</text>The whole thing
Now assemble the layers inside one document, framed by a page template with a footer page number. This is a complete, sendable invoice — and every piece of it is something you met earlier in the book. Edit it, break it, make it yours.
<document version="2.0">
<config>
<page size="A5" margin="28px" />
<meta name="title" value="Invoice #0042" />
<defaults>
<text font="sans" color="#1b1a17" />
</defaults>
</config>
<layout>
<vertical cross="stretch" flex="1">
<content />
<expander />
<line stroke="#ddd5c4" />
<horizontal main="center">
<text size="8" color="#847d6c">Acme & Co. · page
<field name="page"/> of <field name="pages"/></text>
</horizontal>
</vertical>
</layout>
<pages>
<page>
<vertical gap="2px">
<horizontal main="space-between" cross="center"
style:padding="14px 16px" style:background="#1b1a17">
<text size="20" bold="true" color="#faf6ed">Acme & Co.</text>
<vertical cross="end">
<text size="10" color="#9a948a">INVOICE</text>
<text size="14" bold="true" color="#faf6ed">#0042</text>
</vertical>
</horizontal>
<horizontal gap="20px" style:padding="16px 0">
<vertical flex="1" gap="2px">
<text size="9" bold="true" color="#847d6c">BILL TO</text>
<text size="12" bold="true">Wile E. Coyote</text>
<text size="11" color="#3c392f">Desert Route 1, Arizona</text>
</vertical>
<vertical flex="1" cross="end" gap="2px">
<text size="9" bold="true" color="#847d6c">DATE</text>
<text size="12">15 June 2026</text>
<text size="11" color="#3c392f">Due in 30 days</text>
</vertical>
</horizontal>
<table columns="1* 60px 80px" cell-padding="7px"
border="0.6px #ddd5c4 rows outer" stripe="#faf6ed">
<header>
<row background="#1b1a17" color="#ffffff">
<cell bold="true">Description</cell>
<cell bold="true" align="right">Qty</cell>
<cell bold="true" align="right">Amount</cell>
</row>
</header>
<row>
<cell>Rocket-powered roller skates</cell>
<cell align="right">2</cell>
<cell align="right">$240.00</cell>
</row>
<row>
<cell>Giant rubber band, industrial</cell>
<cell align="right">1</cell>
<cell align="right">$75.00</cell>
</row>
<row background="#f0ead9">
<cell bold="true">Total</cell>
<cell />
<cell bold="true" align="right">$315.00</cell>
</row>
</table>
<spacer height="16px" />
<text size="11" color="#3c392f" keep="true"
style:padding="12px" style:background="#faf6ed"
style:border-radius="8px">
Thank you for your business. Payment is due within 30 days; please
reference invoice <b>#0042</b> on your transfer.
</text>
</vertical>
</page>
</pages>
</document>CSS → pdg cheat sheet
Keep this nearby while the vocabulary is still new:
| You want… | CSS | pdg |
|---|---|---|
| A paragraph | <p> |
<text> |
| Bold / italic / link | <strong> <em> <a> |
<b> <i> <a href> |
| A column of items | flex-direction: column |
<vertical> |
| A row of items | flex-direction: row |
<horizontal> |
| Space between children | gap |
gap="…" |
| Distribute / centre | justify-content |
main="space-between", main="center" |
| Align across | align-items |
cross="center", cross="stretch" |
| Grow to fill | flex-grow: 1 |
flex="1" |
| Push to the edge | margin-left: auto |
<expander/> |
| Padding / background / border | the box model | style:padding, style:background, style:border |
| Rounded corners / shadow | border-radius, box-shadow |
style:border-radius, style:box-shadow |
| Layer / z-index | position, z-index |
<stack> |
A card <div> |
a styled <div> |
<box> |
| List / table | <ul> / <table> |
<list> / <table> |
| Running header/footer | position: fixed |
<layout> + <content/> |
| Page number | (print CSS counters) | <field name="page"/> |
Where to go next
- The reference has every element and every
style:property, each with its own live, editable example — the place to look up an exact attribute or default. - The playground is a full-screen editor. Paste any example from this book into it, or start from scratch; the URL holds your whole document, so you can share a draft with a link.
- The Configuration guide goes deeper on fonts, defaults, and document setup when you outgrow the basics.
That is the whole engine. You now know enough to lay out essentially any page — the rest is composition. Go make something, and thank you for reading.