Skip to content

A finished component

The components track builds takeaway — a recommendation with its reasons — across five pages. Here is the whole folder.

lib/components/statement/takeaway/
takeaway.manifest.json ← you write this
takeaway.styles.css ← you write this
takeaway.docs.md ← generated by npm run build
takeaway.gallery.md ← generated
takeaway.gallery.light.pdf ← rendered
takeaway.gallery.dark.pdf ← rendered
examples/
takeaway.md ← the demo deck
takeaway.pdf ← its rendered PDF

Two files are yours.

takeaway.styles.css, entire

Try this. Twenty-two lines. Every selector hangs off > .cell-stage, every color is a token, and space is padding and gap with no margin anywhere — the three rules, in one file you can read at a glance.

{
"name": "takeaway",
"function": "statement",
"form": "canvas",
"substance": "structure",
"bucket": "statement",
"description": "A recommendation stated as a sentence, with its reasons beneath.",
"purpose": "Use when the audience needs to leave holding one position and knowing why.",
"tags": ["recommendation", "positioning", "board-deck"],
"capacity": {
"axis": "item", "sweet": 3, "soft": 4, "hard": 5,
"escalateTo": ["list-tabular"],
"note": "past five reasons it reads as a list, not a position"
},
"density": {
"axis": "item", "soft": 15, "hard": 24,
"note": "about fifteen words per reason"
},
"adapt": { "mode": "native" },
"slots": {
"title": { "selector": "h2", "required": true,
"description": "The recommendation, as one sentence." },
"reasons": { "selector": "ul > li", "required": true,
"description": "One reason per item, in descending weight." }
},
"skeleton": "<!-- _class: takeaway -->\n\n## The recommendation.\n\n- The first reason\n",
"sample": "<!-- _class: takeaway -->\n\n## We should renew the contract.\n\n- Price held flat for two years\n- Migration cost exceeds the saving\n- The team already knows the tool\n",
"stressDoc": {
"summary": "five reasons at the density ceiling",
"sample": "…five reasons, each about twenty-four words…"
},
"whenToUse": [
{ "title": "Close a decision", "body": "The audience has heard the options and needs the recommendation stated once, plainly." },
{ "title": "Open with the answer", "body": "A board deck that leads with its conclusion and supports it after." },
{ "title": "Record a position", "body": "A slide someone will screenshot and paste into a thread." }
],
"antiPatterns": [
{ "title": "More than five reasons", "body": "It stops reading as a position and starts reading as a list — use list-tabular." },
{ "title": "Two recommendations", "body": "One position per slide. A second one halves the weight of both." },
{ "title": "Reasons that are really evidence", "body": "Numbers and citations belong in an evidence layout; these are one-line rationales." }
],
"related": [
{ "name": "list-tabular", "when": "when there are more than five reasons" },
{ "name": "decision", "when": "when the rejected options matter as much as the chosen one" }
]
}

Every field is either a contract or prose someone will read. The axes and slots are the contract. whenToUse, antiPatterns and related are generated into the component’s documentation page — the build emits each section only if you filled it in, so leaving one empty ships a component whose documentation quietly has a hole. Nothing fails; every shipped manifest carries all three by convention, and yours should too.

The capacity numbers came from rendering, not guessing. Five is the hard limit because the sixth reason was tried and it did not work.

axis is item, not reason. It is a closed set — item, row, col, cell, line — and the human word goes in note.

tags come from a fixed vocabulary. They are not free text: validate() checks each one against TAG_GROUPS in lib/components/index.js — sixty terms in four groups — and a further gate rejects a term only one component uses, because a tag that clusters nothing fragments search instead of grouping it. Pick three to five that say something the axes do not; ["statement", "canvas"] would just repeat the manifest.

examples/takeaway.md, six to ten slides, with its PDF committed. It is the only artifact that shows the component under real content — and it is where you find out whether the capacity numbers are honest.