A field guide to rich content on this site
One post to show every writing tool this site supports — from plain Markdown and GitHub Flavored Markdown to the rich-content shortcodes.
This is the reference post. It exists so anyone writing for this site — human or agent — can see exactly which formats render, what they look like, and how they are written. Everything below is live, rendered content, built with Eleventy at build time.
1 · Basic Markdown
Inline emphasis
You can write bold, italic, strikethrough, and code like npm run build. Combine them freely: bold with italic inside still works.
Links
Internal links stay on the site, external links open in a new tab with an arrow icon, and bare URLs autolink automatically: https://www.11ty.dev/docs/languages/markdown/
Lists
Unordered:
- A research interview guide
- A synthesis workshop
- A share-out that asks questions instead of prescribing answers
Ordered:
- Collect the evidence
- Name the tension
- Make the decision visible
Nested:
- Design research
- Interviews
- Diary studies
- Product strategy
- Frame the problem
- Define the option space
A pillar of plain writing
The best insight is useless until someone can act on it.
2 · GitHub Flavored Markdown
Task lists
Tables
| Format | Use it for | Rendered by |
|---|---|---|
| Basic Markdown | Headings, lists, links | markdown-it |
| GFM | Tables, task lists, ~~ |
markdown-it |
| Shortcodes | Figures, callouts, embeds | Eleventy |
Fenced code
function decide(evidence, constraints) {
return evidence
.map((item) => ({ ...item, score: score(item, constraints) }))
.sort((a, b) => b.score - a.score)[0];
}
npm run build # eleventy builds the whole site
npm run start # eleventy --serve with live reload
Hashes, diffs, other GFM
This whole section used to be an assumption. Now it is a checklist.
| Heading | What changed |
|---|---|
# |
Page or post title |
## |
Section heading |
### |
Sub-section |
3 · Rich blocks (the shortcodes)
The shortcodes below are the reason this page can show captioned figures, galleries, callouts, timelines, and more. They are Nunjucks shortcodes registered in .eleventy.js.
{% figure "/assets/images/content-demo/abstract-01.svg", "Abstract composition", "A demo figure with a caption and a credit" %}
Figures and images
Use image when no caption is needed:
Gallery
{% gallery %}
/assets/images/content-demo/abstract-01.svg | First concept
/assets/images/content-demo/abstract-02.svg | Second concept
/assets/images/content-demo/abstract-03.svg | Third concept
{% endgallery %}
Click any image to open it full size.
Video and audio
{% video "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4", "/assets/images/content-demo/poster.svg", "A short CC0 demo video with a local poster." %}
Callouts
The first argument is the callout's title, shown as its label. The preset titles each carry a default color:
{% callout "warning" %}
This block carries real semantic weight. Use it sparingly.
{% endcallout %}
A second argument overrides the accent color with any hex value (or a preset name):
{% callout "Milestone", "#4a8f5f" %}
A custom title with a custom accent color.
{% endcallout %}
The preset titles, rendered:
And a custom title with a custom color — callouts are no longer limited to a fixed set:
Quotes, pullquotes, and captions
{% quote "Mary Oliver" %}
Tell me, what is it you plan to do with your one wild and precious life?
{% endquote %}
Tell me, what is it you plan to do with your one wild and precious life?
A pullquote is centered, borderless, and oversized — editorial emphasis, not attribution:
The system gets out of the way the moment the content earns its place.
And a plain caption for when a short note needs editorial styling:
Borders, mono labels, and hairline rules — the visual language of this site.
Divider
Use Markdown --- for everyday dividers, or {% divider %} when the rule needs a unique style hook:
Expandable details
{% details "Read the boring appendix" %}
Supporting context goes here and stays collapsed by default.
{% enddetails %}
What is GFM anyway?
GitHub Flavored Markdown is CommonMark plus a few practical extensions: tables, task lists, strikethrough, and autolinks. markdown-it covers CommonMark, and the site config adds the remaining GFM pieces.
Aside
{% aside %}
Secondary context that helps but is not part of the main narrative.
{% endaside %}
4 · Actions, links, and metrics
Link card
{% linkcard "https://www.11ty.dev/docs/shortcodes/", "Eleventy shortcodes", "The official documentation for shortcodes — single and paired." %}
11ty.dev
Eleventy shortcodes
The official documentation for shortcodes — single and paired.
Button
{% button "Read the full spec", "/portfolio/atlas/" %}
Metrics
{% metric "42%", "Fewer handoffs between insight and action" %}
5 · Portfolio-style blocks
Timeline
{% timeline %}
{% event "2026-01", "Research" %}
Initial customer interviews with eight owners.
{% endevent %}
{% event "2026-02", "Prototype" %}
A three-round prototype test cycle.
{% endevent %}
{% event "2026-03", "Ship" %}
First release with a content pattern library.
{% endevent %}
{% endtimeline %}
-
Research
Initial customer interviews with eight owners across retail and services.
-
Prototype
A three-round prototype test cycle refining language and thresholds.
-
Ship
First release, shipped with a content pattern library.
Before / after
{% beforeafter "/assets/images/content-demo/before.svg", "/assets/images/content-demo/after.svg", "Before", "After" %}
Drag anywhere on the image to compare. Without JavaScript the split still shows at 50/50.
Columns
{% columns %}
{% column %}
**Reading first.** Start with the prose. Layout never rescues a weak argument.
{% endcolumn %}
{% column %}
**Layout second.** Columns are for genuinely parallel ideas — not for decoration.
{% endcolumn %}
{% endcolumns %}
Reading first. Start with the prose. Layout never rescues a weak argument.
Layout second. Columns are for genuinely parallel ideas — not for decoration.
6 · External embeds
External embeds are opt-in and domain-restricted. Dedicated shortcodes cover the most common services.
{% youtube "M7lc1UVf-VE" %}
{% vimeo "76979871" %}
The generic embed works for anything on the allowlist — here is a Spotify player:
{% embed "https://open.spotify.com/embed/track/4PTG3Z6ehGkBFwjybzWkR8", "A Spotify track embed" %}
Optional embeds — CodePen, Gists, and social posts — follow the same pattern:
{% codepen "team/codepen/pen/WgLbYp" %}
{% gist "11ty/eleventy" %}
{% tweet "https://x.com/eleven_ty/status/1234567890" %}
{% instagram "https://www.instagram.com/p/abc123/" %}
Files to touch
The whole system follows one rule from docs/CONTENT-SPEC.md:
Markdown handles writing. Shortcodes handle meaningfully richer content. CSS handles presentation. JavaScript handles optional interaction.
If you are adding a new post, only the Markdown file matters — the blog collection picks it up automatically.