CSS is Awesome

Print

Print is a themeable surface in css-is-awesome, not an afterthought. One line sets up a clean, legible Print → Save as PDF for any theme — dark themes included — and four tokens let a theme, or a single project, give paper its own identity. Zero JavaScript: the page is the PDF source and the browser is the generator.

The print palette

cia.print-base defines four custom properties that describe the printed page. Their default is clean ink-on-white with light grays, which every theme inherits with no work:

--print-ink     /* body text, links, code text   — default #000 */
--print-paper   /* backgrounds                   — default #fff */
--print-line    /* borders, rules, hairlines     — default #999 */
--print-muted   /* printed URLs, captions        — default #666 */

How print colour works

Inside @media print, print-base forces color-scheme: light (so paired light-dark() themes print their light branch) and then rebinds the theme’s own colour tokens onto the palette — --ink, --surface-*, --border-* and --code-* all resolve to the --print-* values. The effect: every element that reads a theme token prints as ink on paper, so a dark-only theme like Terminal is legible with no flag, and overriding a single --print-* token re-inks the whole page.

This replaces the old $legible flag, which is now a deprecated no-op — the rebind supersedes it, and passing it emits a build warning. The other flags remain: $link-urls and $link-origin print each link’s full destination via attr(href), and $page-numbers puts sheet numbers in the @page footer.

Setup

Include print-base once at the root of a global stylesheet — it emits its own :root block plus @page, so it can’t live inside a component module or a selector. Then hide chrome and reveal paper-only content with print-hidden / print-only.

@use 'css-is-awesome/api' as cia;

// Once, in a GLOBAL stylesheet. Optional flags:
//   ($size, $margin, $freeze-animations, $link-urls, $link-origin, $page-numbers)
@include cia.print-base($link-urls: true, $page-numbers: true);

.site-nav   { @include cia.print-hidden; } // drop chrome on paper
.print-note { @include cia.print-only; }   // reveal paper-only content

Full mixin reference in Mixins → Print / PDF.

A theme’s own paper look

The default is clean ink-on-white, and most themes want exactly that on paper — nobody wants a neon dashboard’s glow on a printout. A theme that does want a paper identity overrides the palette in its own @media print block — one file, per the theme architecture. The shipped Press theme does this: newsprint stock, warm ink, press-red masthead rules.

// inside a theme's own file — Press's newsprint print identity
@media print {
  --print-paper: #FBFAF6;  // faint warm stock
  --print-ink:   #0A0A0A;  // warm near-black
  --print-line:  #D93025;  // press red rules
  --print-muted: #6B6963;
}

A shareable paper style that isn’t tied to one theme — a corporate letterhead palette — ships instead as a print-only overlay you drop onto any theme, the same mechanism paired light/dark themes use:

<link rel="stylesheet" href="/themes/letterhead/print.css" media="print">

The letterhead

A letterhead — a branded header on the paper that isn’t on screen — is markup you add, not a theme. It’s a print-only block styled with cia.print-only and the --print-* palette, so it appears on paper only and matches whatever the print colours are. The full pattern, with framework examples, is the letterhead recipe.

Preview & edit in the theme editor

Because --print-* tokens only act in @media print, editing them live shows nothing on screen — so the theme editor has a 🖨 Print button that opens a paper preview. It simulates the printed page on screen (the same token rebind, applied live), lets you edit the four palette colours and toggle a letterhead, and copies the ready-to-paste @media print block for your theme. It opens seeded from that theme’s own @media print override when it has one (Press opens straight into newsprint), and remembers your edits per theme family the next time you open it.

See it work

The print-to-pdf example is a real invoice you Ctrl+P: the site chrome drops, an ACME letterhead appears, the invoice fills the sheet, links print as full URLs, a sheet number appears, and a build-time print-only QR code links the paper back to the live page. Walkthroughs: the print-to-pdf and print-spec recipes.

Theme