Ship your finish
A finish is finished when it works in every palette, in both canvases, and — the part no script can check — in the exported PDF. This page is that list.
What you touch
Section titled “What you touch”lib/finishes/quarry/quarry.manifest.json ← name, label, blurb, order, swatchlib/finishes/quarry/quarry.recipe.json ← the look, for "Start from preset"lib/base/base.finish.css ← the preset blockdesign/skills/finish.md ← the count of shipped finishesexamples/quarry.md + quarry.pdf ← the demo deckThe package folder is the whole registration: the engine’s register, the lint vocabulary, the Studio’s picker and its reserved-name list are generated from it. The CSS block is the real work.
The checklist
Section titled “The checklist”The preset
- Package folder added (
lib/finishes/quarry/: manifest + recipe), andnode tools/build-packages-index.jsrun. - All four slot families declared. Unused background slots are
none; unused--fin-frameis0 0 transparent—noneis invalid in a shadow list and silently kills the tone rail. - Every full-bleed layer has a
-opaquetwin ending onvar(--fin-canvas). - The two faces have the same layer count.
-
--fin-size,--fin-positionand--fin-repeateach carry one entry per layer, in the same order the layers are listed: texture first, then wash. - Accent alpha stays in the 5–16% range wherever a layer covers the whole page. A narrow band — an edge strip, a mark bar — may go higher.
- Both mark slots declared:
--fin-mark: noneand--fin-mark-text: "". - A full frame uses
--fin-frame, not the section’s::after. - A frame also sets
--fin-frame-markto its keyline color, or it is lost in every export.
Palette-blind
- Every color is a
color-mix()ofvar(--accent),var(--fin-canvas)orvar(--text-heading). - No hex literals, no
url(), nomask-image, nomargin.
Around it
- The shipped-finish count in
design/skills/finish.mdbumped — the ownership guard checks it against the register. -
examples/quarry.mdwritten, six to ten slides, PDF committed. - A changelog fragment in
changelog.d/. -
npm run build:checkgreen. -
npm testgreen.
The sign-off no script can do
- Exported through both engines — the command-line PDF and the in-browser export — in both canvases, all four files opened and looked at.
That last one is a hard requirement. A finish changes the bytes of every exported file, and its failure mode — a gray cloud across a full-bleed fade, a title slide washed to near-blank — appears only in the export. Nothing on screen predicts it.
Six ways a finish goes wrong
Section titled “Six ways a finish goes wrong”- A fade ending on
transparentin the opaque face. A gray cloud in every PDF. - Accent alpha too high across the full page. The backdrop competes with the words.
--fin-frame: none. Invalid inside a shadow list, so the declaration dies and takes the tone rail with it. Use0 0 transparent.url(),mask-image, a hex, or amarginanywhere in the preset.- A monogram baked into a deck-wide finish.
- Mismatched layer counts between the two faces, which quietly corrupts the shared size and position lists.
Where to go next
Section titled “Where to go next”- Pick the colors it will wear: Theme anatomy.
- Arrange what sits on top of it: Component anatomy.
- Build one from dropdowns and sliders instead: the Studio has a finish workbench that writes this CSS for you.