diff --git a/site/_tests/01-tide-podcast/brief.md b/site/_tests/01-tide-podcast/brief.md
new file mode 100644
index 0000000..f56a59f
--- /dev/null
+++ b/site/_tests/01-tide-podcast/brief.md
@@ -0,0 +1,42 @@
+# Test 01 — Tide (indie podcast)
+
+## The prompt
+
+> "build me a landing page for my indie podcast called Tide. just go ahead, you pick."
+
+## Context gate — skipped
+
+The user opted out of the gate. The skill must state its inferences in one sentence at the top of its reply.
+
+**Going with:** *audience = listeners who care about voice and atmosphere · use = listen + subscribe · tone = intimate, considered, voice-led.* If any of those is wrong, redirect.
+
+## Domain inference
+
+`podcast` → audio domain. From `references/structure.md`'s domain trio table: **Photographic / Quote-Led / Letter** are the three suggested macrostructures.
+
+The skill picks **Quote-Led** because the medium is voice — a pull-quote from a hypothetical listener carries the weight a stat or a feature grid couldn't.
+
+## Theme
+
+No theme requested. Picking **Atelier** — italic Cormorant-style display, calm cream paper, generous whitespace. Audio podcasts inhabit a quiet listening posture; Atelier matches.
+
+## Enrichment
+
+Typography only. The hero is a quote. Reaching for a Lottie loop, an illustration, or a stock-podcaster photo would dilute the voice.
+
+## Macrostructure stamp
+
+```
+/* Hallmark · macrostructure: Quote-Led · H3 hero knobs: weight=italic display, attribution=under quote, length=80–160 chars
+ * theme: Atelier · accent: terracotta ~2% · enrichment: none (typography only)
+ * studied: no · context: skipped, inferred (audio domain)
+ */
+```
+
+## What the page does
+
+- Italic display pull-quote at the top, no headline above
+- Listener attribution in small caps below
+- One paragraph of host-voice copy below the quote
+- Three thin platform links (Apple / Spotify / RSS) — typographic only, no platform icons (icon-set tell)
+- Footer: a single dense line, monospace
diff --git a/site/_tests/01-tide-podcast/index.html b/site/_tests/01-tide-podcast/index.html
new file mode 100644
index 0000000..7a684dd
--- /dev/null
+++ b/site/_tests/01-tide-podcast/index.html
@@ -0,0 +1,45 @@
+
+
+
+
+
+ Tide — a podcast about the things that come back
+
+
+
+
+
+
Tide · Episode 14 · listening from anywhere
+
+
+ I started listening on a long bus ride. By the third episode I'd missed my stop, and I didn't mind.
+
+
+
— A listener · Lisbon · 2026
+
+
+ Tide is a small fortnightly podcast about the things in life that keep coming back — old letters, slow recipes, the way a song sounds different in winter. Half-hour episodes, hosted by Mira Aoki. New episode every other Tuesday.
+
Files, pipes, sockets, kubectl logs. Streampipe reads from stdin by default; --from takes a path or URL. Detects format on the first 100 lines (json, ndjson, syslog, common, custom regex).
+
+
+
+
+ 2.0 / filter
+
+
Express filters in a small language, not in regex.
+
Filters compile to a typed predicate AST: status >= 500, duration_ms > 200 and path ~ "/api/", host in {a, b, c}. No quoting hell, no shell-specific escaping.
+
+
--filter
predicate expression
repeatable
+
--from
file path, URL, or `-` for stdin
default: stdin
+
--out
ndjson · csv · text · table
default: ndjson
+
--at
truncate after N records
optional
+
--debug
show parse stats
optional
+
+
+
+
+
+ 3.0 / route
+
+
Compose with anything that takes lines.
+
Streampipe is line-oriented all the way through. Pipe its output into jq, gron, vmctl, kafkacat, or your own thing. No daemon, no agent, no config file unless you want one.
+
+
+
+
+
+
+
diff --git a/site/_tests/02-streampipe-cli/style.css b/site/_tests/02-streampipe-cli/style.css
new file mode 100644
index 0000000..21e8be5
--- /dev/null
+++ b/site/_tests/02-streampipe-cli/style.css
@@ -0,0 +1,239 @@
+/* Hallmark · macrostructure: Workbench · F2 sticky-scroll knobs: pinned=right, content=code, steps=3
+ * theme: Terminal · accent: phosphor-green ~6% (functional, not decorative) · enrichment: E1 hero — pure-CSS terminal mockup (Tier A)
+ * studied: no · context: explicit
+ */
+
+@import url("https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500&display=swap");
+
+:root {
+ --paper: oklch(11% 0.018 145); /* deep cool dark, slight green */
+ --paper-2: oklch(15% 0.020 145);
+ --paper-3: oklch(20% 0.020 145);
+ --rule: oklch(28% 0.015 145);
+ --rule-2: oklch(40% 0.025 145);
+ --muted: oklch(58% 0.025 145);
+ --ink-2: oklch(82% 0.020 145);
+ --ink: oklch(94% 0.012 145);
+ --accent: oklch(78% 0.19 138); /* phosphor green */
+ --accent-2: oklch(86% 0.16 138);
+
+ --mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
+ --space-xs: 0.5rem;
+ --space-sm: 0.75rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2.5rem;
+ --space-2xl: 4rem;
+ --space-3xl: 6rem;
+
+ --rule-hair: 0.5px;
+ --rule-fine: 1px;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+html {
+ font-family: var(--mono);
+ font-size: 14px;
+ line-height: 1.55;
+ color: var(--ink-2);
+ background: var(--paper);
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ min-height: 100dvh;
+ padding-inline: clamp(1.5rem, 5vw, 4rem);
+ padding-block: var(--space-2xl);
+ max-width: 76rem;
+ margin: 0 auto;
+}
+
+.nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ padding-block: var(--space-md);
+ border-block-end: var(--rule-hair) solid var(--rule);
+ margin-block-end: var(--space-3xl);
+}
+.nav .wordmark { color: var(--ink); }
+.nav .wordmark::before { content: "$ "; color: var(--accent); }
+.nav__links { display: flex; gap: var(--space-lg); }
+.nav__links a {
+ color: var(--muted);
+ text-decoration: none;
+ text-underline-offset: 4px;
+}
+.nav__links a:hover { color: var(--ink); text-decoration: underline; }
+
+/* Hero — headline + CSS-art terminal mockup */
+.hero {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-2xl);
+ align-items: start;
+ margin-block-end: var(--space-3xl);
+ padding-block-end: var(--space-2xl);
+ border-block-end: var(--rule-hair) solid var(--rule);
+}
+
+.hero__headline {
+ font-family: var(--mono);
+ font-size: clamp(1.75rem, 3vw + 0.5rem, 2.75rem);
+ font-weight: 500;
+ letter-spacing: -0.005em;
+ color: var(--ink);
+ line-height: 1.1;
+}
+.hero__headline .prompt { color: var(--accent); }
+
+.hero__lede {
+ margin-block-start: var(--space-lg);
+ color: var(--ink-2);
+ max-width: 40ch;
+}
+
+.hero__cta {
+ margin-block-start: var(--space-xl);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-sm);
+}
+.hero__cta-label {
+ color: var(--muted);
+ font-size: 0.75rem;
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+}
+.cmd {
+ background: var(--paper-2);
+ border: var(--rule-hair) solid var(--rule);
+ padding: var(--space-md) var(--space-lg);
+ color: var(--ink);
+ display: flex;
+ align-items: center;
+ gap: var(--space-md);
+}
+.cmd .prompt { color: var(--accent); user-select: none; }
+
+/* CSS-art terminal mockup — pure CSS, no images, no Lottie */
+.term {
+ background: var(--paper-3);
+ border: var(--rule-hair) solid var(--rule-2);
+ font-family: var(--mono);
+ font-size: 0.8125rem;
+ line-height: 1.7;
+ padding: var(--space-md) var(--space-lg);
+ color: var(--ink-2);
+ display: grid;
+ gap: 0.05rem;
+ position: relative;
+ overflow: hidden;
+}
+.term::before {
+ content: "";
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 28px;
+ background: var(--paper-2);
+ border-block-end: var(--rule-hair) solid var(--rule);
+}
+.term::after {
+ content: "streampipe — 80×24";
+ position: absolute;
+ top: 6px; left: 12px;
+ font-size: 0.6875rem;
+ color: var(--muted);
+ letter-spacing: 0.04em;
+}
+.term { padding-block-start: 2.6rem; }
+
+.term .ln { display: block; white-space: pre; }
+.term .prompt { color: var(--accent); }
+.term .flag { color: var(--accent-2); }
+.term .num { color: var(--ink); font-weight: 500; }
+.term .meta { color: var(--muted); }
+.term .caret {
+ display: inline-block;
+ width: 0.55em;
+ height: 1em;
+ background: var(--accent);
+ vertical-align: -0.15em;
+ margin-inline-start: 0.05em;
+ animation: blink 1.05s steps(2) infinite;
+}
+@keyframes blink { to { background: transparent; } }
+@media (prefers-reduced-motion: reduce) {
+ .term .caret { animation: none; }
+}
+
+/* Section heads — left-margin numbered (Workbench style) */
+.section {
+ display: grid;
+ grid-template-columns: 6rem 1fr;
+ gap: var(--space-lg);
+ margin-block-end: var(--space-3xl);
+ padding-block-end: var(--space-2xl);
+ border-block-end: var(--rule-hair) solid var(--rule);
+ align-items: baseline;
+}
+
+.section__num {
+ font-family: var(--mono);
+ font-size: 0.8125rem;
+ color: var(--muted);
+ letter-spacing: 0.06em;
+}
+.section__num span { color: var(--accent); }
+
+.section__title {
+ font-family: var(--mono);
+ font-size: 1.25rem;
+ font-weight: 500;
+ color: var(--ink);
+ margin-block-end: var(--space-md);
+ letter-spacing: -0.005em;
+}
+.section__body { color: var(--ink-2); max-width: 60ch; }
+.section__body code { color: var(--accent-2); background: transparent; }
+
+/* Spec sheet (F3) — flags */
+.spec {
+ display: grid;
+ grid-template-columns: 12rem 1fr 1fr;
+ gap: var(--space-md);
+ font-family: var(--mono);
+ font-size: 0.8125rem;
+ margin-block-start: var(--space-lg);
+}
+.spec > * {
+ padding-block: var(--space-sm);
+ border-block-start: var(--rule-hair) solid var(--rule);
+}
+.spec dt {
+ color: var(--accent-2);
+}
+.spec dd { margin: 0; color: var(--ink-2); }
+.spec .meta { color: var(--muted); }
+
+/* Footer — dense colophon */
+footer {
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ line-height: 1.7;
+ color: var(--muted);
+ white-space: pre-wrap;
+ padding-block: var(--space-2xl);
+ border-block-start: var(--rule-hair) solid var(--rule);
+}
+footer .ink { color: var(--ink); }
+footer a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 4px; }
+
+@media (max-width: 56rem) {
+ .hero { grid-template-columns: 1fr; }
+ .section { grid-template-columns: 1fr; }
+ .section__num { color: var(--accent); }
+ .spec { grid-template-columns: 8rem 1fr; }
+ .spec .meta { display: none; }
+}
diff --git a/site/_tests/03-maple-bakery/brief.md b/site/_tests/03-maple-bakery/brief.md
new file mode 100644
index 0000000..496fdb6
--- /dev/null
+++ b/site/_tests/03-maple-bakery/brief.md
@@ -0,0 +1,47 @@
+# Test 03 — Maple Street Bread (artisan bakery)
+
+## The prompt
+
+> "Landing page for Maple Street Bread. Audience: locals who want to buy bread. Use: see what's available + visit. Tone: warm, hand-set, considered."
+
+## Context gate — fully answered
+
+Audience, use, tone all explicit. No inference needed.
+
+## Domain inference
+
+`bakery / kitchen / café / atelier + craft brief` → from the domain table: **Photographic / Long Document / Catalogue**.
+
+The skill picks **Long Document**. The bakery is a story-led brand — there's an owner, a process, a daily rhythm — and a Long Document treats that as prose first, with the menu as a quiet aside. Catalogue (a uniform grid of breads) was the runner-up; Long Document wins because the *narrative* is the differentiator from a corporate bakery chain.
+
+## Theme
+
+No theme requested. Picking **Linen** — warm beige paper, plain serif, hanging headings, generous space. Linen is the only theme that reads as "shop in a real neighbourhood". Salon would be too formal; Garden too literal.
+
+## Enrichment
+
+**E5 Custom Illustration Centerpiece, Tier B (hand-built SVG).** The bakery brief is the canonical example for going custom — a hand-drawn loaf in 60 lines of SVG, three paths, with a `@property`-driven subtle breathing animation.
+
+The decision is *not* to pull a Storyset bakery illustration; that would be the library shortcut. *Not* a Lottie of a baker; that's the Lottie shortcut. *Not* a Midjourney bread photograph; raw output reads as AI. **Hand-built is the right tier here.**
+
+## Macrostructure stamp
+
+```
+/* Hallmark · macrostructure: Long Document · H5 hero knobs: salutation=time-stamp, body=2 paragraphs, signoff=initials
+ * theme: Linen · accent: warm-amber ~3%
+ * enrichment: E5 Custom Illustration · craft: tier-B hand-built SVG (3 paths, 58 lines)
+ * animation: @property --rise · 6s alternate · reduced-motion: static
+ * studied: no · context: explicit
+ */
+```
+
+## What the page does
+
+- A time-stamped salutation ("Saturday, 6:14 a.m.") instead of a brand name banner — the bakery introduces itself as a moment in the day
+- A two-paragraph letter-style body about who bakes and what's baked
+- A hand-drawn SVG loaf, animated with a slow breath
+- A small handwritten-feel "today's loaves" list as marginalia
+- Address + hours in italic at the bottom
+- No buttons, no CTA chip, no "Order online" call. Just a phone number, a street address, and an open-hours range.
+
+The page is small. It's supposed to be.
diff --git a/site/_tests/03-maple-bakery/index.html b/site/_tests/03-maple-bakery/index.html
new file mode 100644
index 0000000..7dc3384
--- /dev/null
+++ b/site/_tests/03-maple-bakery/index.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+ Maple Street Bread — sourdough, baked overnight, sold fresh
+
+
+
+
+
+
Maple Street · est. 2026 · n.º 47
+
+
+
+
+
Saturday, 6:14 a.m.
+
+
The dough went in at midnight. By the time the lights are on outside, the bench is dusted, the loaves are scored, and the oven is hotter than a summer roof. We bake what we baked yesterday and what we'll bake tomorrow — sourdough, slow, by hand, on stone — because that's the bread we wanted to eat when we moved here ten years ago and couldn't find any.
+
+
The shop opens at seven. There are usually thirty loaves and they're usually gone by noon. We don't do online orders. We don't deliver. If you want a loaf, walk over. Bring a bag.
+
+
+
+
Plate 47 · scored before the proof
+
+
+
The oven runs on local oak. The flour is from a mill three hours west. The starter is from a baker in Évora who taught us in 2014 and is still alive. None of these are marketing claims; they are how the bread happens.
+
+
+ Thank you for walking over,
+ — H. & N.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/site/_tests/03-maple-bakery/style.css b/site/_tests/03-maple-bakery/style.css
new file mode 100644
index 0000000..3895109
--- /dev/null
+++ b/site/_tests/03-maple-bakery/style.css
@@ -0,0 +1,253 @@
+/* Hallmark · macrostructure: Long Document · H5 hero knobs: salutation=time-stamp, body=2 paragraphs, signoff=initials
+ * theme: Linen · accent: warm-amber ~3%
+ * enrichment: E5 Custom Illustration · craft: tier-B hand-built SVG (3 paths, 58 lines)
+ * animation: @property --rise · 6s alternate · reduced-motion: static
+ * studied: no · context: explicit
+ */
+
+@import url("https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;1,6..72,400;1,6..72,500&display=swap");
+
+:root {
+ --paper: oklch(89% 0.022 95);
+ --paper-2: oklch(86% 0.024 95);
+ --rule: oklch(78% 0.020 95);
+ --rule-2: oklch(66% 0.024 95);
+ --muted: oklch(46% 0.022 90);
+ --ink-2: oklch(22% 0.025 90);
+ --ink: oklch(15% 0.025 90);
+ --accent: oklch(54% 0.16 50); /* warm amber */
+ --crust: oklch(72% 0.16 55);
+ --crust-deep: oklch(48% 0.14 38);
+
+ --serif: "Newsreader", "Tiempos", ui-serif, Georgia, serif;
+ --label: ui-monospace, "JetBrains Mono", monospace;
+
+ --space-xs: 0.5rem;
+ --space-sm: 0.75rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2.5rem;
+ --space-2xl: 4rem;
+ --space-3xl: 7rem;
+
+ --rule-hair: 0.5px;
+}
+
+@property --rise {
+ syntax: "";
+ initial-value: 0px;
+ inherits: false;
+}
+
+@property --bake {
+ syntax: "";
+ initial-value: 0%;
+ inherits: false;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+html {
+ font-family: var(--serif);
+ font-size: 17px;
+ line-height: 1.65;
+ color: var(--ink-2);
+ background: var(--paper);
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ min-height: 100dvh;
+ padding-inline: clamp(1.5rem, 6vw, 5rem);
+ padding-block: var(--space-3xl) var(--space-2xl);
+ max-width: 64rem;
+ margin: 0 auto;
+}
+
+.eyebrow {
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-block-end: var(--space-2xl);
+}
+
+.layout {
+ display: grid;
+ grid-template-columns: 7fr 4fr;
+ gap: var(--space-3xl);
+ align-items: start;
+}
+
+@media (max-width: 56rem) {
+ .layout { grid-template-columns: 1fr; gap: var(--space-2xl); }
+}
+
+.salutation {
+ font-family: var(--serif);
+ font-style: italic;
+ font-weight: 400;
+ font-size: clamp(2.25rem, 4vw + 1rem, 3.6rem);
+ line-height: 1.1;
+ letter-spacing: -0.018em;
+ color: var(--ink);
+ margin-block-end: var(--space-xl);
+}
+
+.letter p {
+ font-size: 1.0625rem;
+ line-height: 1.72;
+ margin-block-end: var(--space-md);
+ max-width: 36rem;
+}
+
+.letter p:first-of-type::first-letter {
+ font-family: var(--serif);
+ font-size: 3.6em;
+ font-weight: 500;
+ line-height: 0.9;
+ float: left;
+ margin-block-start: 0.08em;
+ margin-inline-end: 0.1em;
+ color: var(--accent);
+}
+
+.signoff {
+ margin-block-start: var(--space-xl);
+ font-family: var(--serif);
+ font-style: italic;
+ color: var(--muted);
+}
+
+.signoff strong {
+ display: block;
+ font-style: normal;
+ font-weight: 500;
+ color: var(--ink);
+ margin-block-start: 0.2em;
+ font-size: 1.125rem;
+}
+
+/* The aside — today's loaves + visit */
+.aside {
+ font-family: var(--serif);
+ font-size: 0.9375rem;
+ line-height: 1.65;
+ color: var(--ink-2);
+ border-inline-start: var(--rule-hair) solid var(--rule);
+ padding-inline-start: var(--space-lg);
+ position: sticky;
+ top: var(--space-2xl);
+}
+
+@media (max-width: 56rem) {
+ .aside { border-inline-start: 0; padding-inline-start: 0; padding-block-start: var(--space-xl); border-block-start: var(--rule-hair) solid var(--rule); position: static; }
+}
+
+.aside h3 {
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ font-weight: 400;
+ margin-block: var(--space-xl) var(--space-md);
+}
+
+.aside h3:first-child { margin-block-start: 0; }
+
+.aside ul {
+ list-style: none;
+ display: grid;
+ gap: 0.4em;
+}
+
+.aside li {
+ display: flex;
+ justify-content: space-between;
+ gap: var(--space-md);
+ font-style: italic;
+}
+
+.aside li .price {
+ font-style: normal;
+ font-variant-numeric: tabular-nums;
+ color: var(--muted);
+ font-family: var(--label);
+ font-size: 0.8125rem;
+}
+
+.aside p {
+ font-style: italic;
+ color: var(--ink-2);
+}
+
+.aside .phone {
+ font-family: var(--label);
+ font-style: normal;
+ font-size: 0.875rem;
+ color: var(--ink);
+}
+
+/* The loaf — hand-built SVG centerpiece */
+.loaf-wrap {
+ margin-block: var(--space-2xl) var(--space-xl);
+ text-align: center;
+}
+
+.loaf-svg {
+ width: 100%;
+ max-width: 22rem;
+ height: auto;
+ display: block;
+ margin: 0 auto;
+ transform: translateY(var(--rise));
+ animation: rise 6s ease-in-out infinite alternate;
+ filter: drop-shadow(0 14px 18px oklch(28% 0.04 50 / 0.12));
+}
+
+@keyframes rise { to { --rise: -4px; } }
+
+.loaf-body { fill: var(--crust); }
+.loaf-shade { fill: var(--crust-deep); opacity: 0.18; }
+.loaf-score {
+ stroke: var(--crust-deep);
+ stroke-width: 2.5;
+ stroke-linecap: round;
+ fill: none;
+ stroke-dasharray: 0 240;
+ animation: score 1.6s 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;
+}
+@keyframes score { to { stroke-dasharray: 240 240; } }
+
+.loaf-cap {
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.14em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-block-start: var(--space-md);
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .loaf-svg { animation: none; --rise: 0px; }
+ .loaf-score { animation: none; stroke-dasharray: 240 240; }
+}
+
+footer {
+ margin-block-start: var(--space-3xl);
+ padding-block: var(--space-lg);
+ border-block-start: var(--rule-hair) solid var(--rule);
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.06em;
+ color: var(--muted);
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--space-md);
+}
+
+footer .ink { color: var(--ink); }
+footer .sep { color: var(--rule-2); }
diff --git a/site/_tests/04-meridian-manifesto/brief.md b/site/_tests/04-meridian-manifesto/brief.md
new file mode 100644
index 0000000..c7a9b16
--- /dev/null
+++ b/site/_tests/04-meridian-manifesto/brief.md
@@ -0,0 +1,49 @@
+# Test 04 — Meridian (studio manifesto)
+
+## The prompt
+
+> "Make me a manifesto for my new studio called Meridian. We work on environmental products. No flashy stuff."
+
+## Context gate — partial
+
+User gave audience-implied (people who care about environmental products) and tone (declarative, no flash). Skill infers the rest:
+
+**Going with:** *audience = potential clients and collaborators · use = read our position · tone = declarative, polemical, restrained.*
+
+## Domain inference
+
+`manifesto / cause / advocacy` → from the domain table: **Manifesto / Quote-Led / Stat-Led**.
+
+The skill picks **Manifesto** (the brief literally names it). This is the rare case where the macrostructure name and the brief word are the same — which is fine, because Manifesto-the-macrostructure is genuinely a *page shape*, not a default we should run from.
+
+## Theme
+
+The user said "no flashy stuff" — that's the strongest possible cue against ornament. Picking **Manifesto** the theme too: pure black paper, oversized solid type, single red accent, no gradients, no rounded corners. The theme name + macrostructure name aligning is honest here, not lazy.
+
+(Salon, Studio, Pastel would all be wrong tonally. Brutal would have worked but is a touch louder.)
+
+## Enrichment
+
+**None.** Typography is the design. The page makes its point in five short declarations and stops.
+
+The slop test catches: no abstract background gradient, no Lottie loop, no illustration, no demo video. The voice is the page.
+
+## Macrostructure stamp
+
+```
+/* Hallmark · macrostructure: Manifesto · H1 hero knobs: size=xxl, alignment=left-bias, underlay=none
+ * theme: Manifesto · accent: red ~5% (used as bleed dividers, not flood)
+ * enrichment: none (typography only — voice is the design)
+ * studied: no · context: partial, inferred (audience + use)
+ */
+```
+
+## What the page does
+
+- Five short declarations stacked vertically, each on its own page-fold-sized band
+- A single red bleed-colour band between the third and fourth declaration as the only visual ornament
+- Numbered "I." through "V." in display weight on the left margin of each declaration
+- A signed colophon at the bottom: studio name, year, three signatories
+- No links. No CTA. No "Learn more". A manifesto is not a marketing page.
+
+The page is mostly black. It is supposed to be.
diff --git a/site/_tests/04-meridian-manifesto/index.html b/site/_tests/04-meridian-manifesto/index.html
new file mode 100644
index 0000000..6c7d7d2
--- /dev/null
+++ b/site/_tests/04-meridian-manifesto/index.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+ Meridian — a manifesto
+
+
+
+
+
+
+ Meridian
+ 2026 · A MANIFESTO · IN FIVE PARTS
+
+
+
+
WE ARE A STUDIO. WE ARE NOT A PLATFORM.
+
— a position, signed by three of us, on the practice of building environmental products in 2026.
+
+
+
+ I.
+
We design products that last twelve years. We do not design products that need replacing every two.
+
+
+
+ II.
+
A material is not "sustainable" because the brochure says so. A material is sustainable because someone, somewhere, can repair it.
+
+
+
+ III.
+
We do not believe in growth. We believe in fit. A studio of three is the studio we want to remain.
+
+
+
+
This is not a roadmap. This is what we believe before we open the laptops.
+
+
+
+ IV.
+
If our work cannot be made by hand somewhere, we are not the right studio for it. We will recommend a friend.
+
+
+
+ V.
+
We will not put our work behind a chatbot. We will answer the email ourselves, or not at all.
+
+
+
+
+
+
diff --git a/site/_tests/04-meridian-manifesto/style.css b/site/_tests/04-meridian-manifesto/style.css
new file mode 100644
index 0000000..e2134c6
--- /dev/null
+++ b/site/_tests/04-meridian-manifesto/style.css
@@ -0,0 +1,185 @@
+/* Hallmark · macrostructure: Manifesto · H1 hero knobs: size=xxl, alignment=left-bias, underlay=none
+ * theme: Manifesto · accent: red ~5% (used as bleed dividers, not flood)
+ * enrichment: none (typography only — voice is the design)
+ * studied: no · context: partial, inferred (audience + use)
+ */
+
+@import url("https://fonts.googleapis.com/css2?family=Inter+Tight:wght@500;700;800;900&family=JetBrains+Mono:wght@400;500&display=swap");
+
+:root {
+ --paper: oklch(10% 0.005 60);
+ --paper-2: oklch(14% 0.006 60);
+ --rule: oklch(28% 0.008 60);
+ --muted: oklch(58% 0.010 60);
+ --ink-2: oklch(85% 0.005 60);
+ --ink: oklch(98% 0.003 90);
+ --accent: oklch(60% 0.22 27);
+
+ --display: "Inter Tight", "Söhne Breit", system-ui, sans-serif;
+ --label: "JetBrains Mono", ui-monospace, monospace;
+
+ --space-xs: 0.5rem;
+ --space-sm: 0.75rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2.5rem;
+ --space-2xl: 4rem;
+ --space-3xl: 8rem;
+ --space-4xl: 12rem;
+
+ --rule-fine: 2px;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+html {
+ font-family: var(--display);
+ font-size: 17px;
+ line-height: 1.4;
+ color: var(--ink);
+ background: var(--paper);
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ min-height: 100dvh;
+}
+
+.masthead {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ padding: var(--space-lg) clamp(1.5rem, 6vw, 4rem);
+ border-block-end: var(--rule-fine) solid var(--ink);
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+}
+
+.masthead .name {
+ font-family: var(--display);
+ font-weight: 800;
+ font-size: 1rem;
+ letter-spacing: -0.005em;
+ text-transform: uppercase;
+}
+
+.masthead .meta { color: var(--muted); }
+.masthead .meta .accent { color: var(--accent); }
+
+.title {
+ padding: var(--space-3xl) clamp(1.5rem, 6vw, 4rem) var(--space-2xl);
+ border-block-end: var(--rule-fine) solid var(--ink);
+}
+
+.title h1 {
+ font-family: var(--display);
+ font-weight: 900;
+ font-size: clamp(3rem, 8vw + 1rem, 7.5rem);
+ line-height: 0.92;
+ letter-spacing: -0.035em;
+ text-transform: uppercase;
+ color: var(--ink);
+ max-width: 18ch;
+}
+
+.title h1 em {
+ font-style: normal;
+ color: var(--accent);
+}
+
+.title .subtitle {
+ font-family: var(--label);
+ font-size: 0.75rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--muted);
+ margin-block-start: var(--space-xl);
+}
+
+.declaration {
+ display: grid;
+ grid-template-columns: clamp(4rem, 10vw, 8rem) 1fr;
+ gap: var(--space-xl);
+ padding: var(--space-3xl) clamp(1.5rem, 6vw, 4rem);
+ border-block-end: var(--rule-fine) solid var(--ink);
+ align-items: baseline;
+}
+
+.declaration__num {
+ font-family: var(--display);
+ font-weight: 800;
+ font-size: clamp(2rem, 4vw + 0.5rem, 3.5rem);
+ letter-spacing: -0.01em;
+ color: var(--accent);
+ line-height: 0.9;
+}
+
+.declaration__body {
+ font-family: var(--display);
+ font-weight: 700;
+ font-size: clamp(1.5rem, 3vw + 0.5rem, 2.625rem);
+ line-height: 1.12;
+ letter-spacing: -0.018em;
+ color: var(--ink);
+ max-width: 28ch;
+ text-transform: uppercase;
+}
+
+.declaration__body strong {
+ background: var(--accent);
+ color: var(--paper);
+ padding: 0 0.18em;
+ font-weight: 700;
+}
+
+/* Bleed-colour ornament between III and IV */
+.bleed {
+ background: var(--accent);
+ padding: var(--space-2xl) clamp(1.5rem, 6vw, 4rem);
+ border-block-end: var(--rule-fine) solid var(--ink);
+}
+
+.bleed p {
+ font-family: var(--display);
+ font-weight: 800;
+ font-size: clamp(1.25rem, 2vw + 0.5rem, 1.75rem);
+ letter-spacing: -0.01em;
+ color: var(--paper);
+ text-transform: uppercase;
+ max-width: 38ch;
+}
+
+.colophon {
+ padding: var(--space-3xl) clamp(1.5rem, 6vw, 4rem);
+ display: grid;
+ gap: var(--space-md);
+ font-family: var(--label);
+ font-size: 0.8125rem;
+ letter-spacing: 0.06em;
+ color: var(--muted);
+ line-height: 1.7;
+}
+
+.colophon h2 {
+ font-family: var(--display);
+ font-weight: 800;
+ font-size: 1rem;
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--ink);
+ margin-block-end: var(--space-sm);
+}
+
+.colophon .signed {
+ display: grid;
+ gap: 0.4em;
+ color: var(--ink-2);
+ margin-block-start: var(--space-md);
+}
+
+.colophon .signed strong {
+ color: var(--ink);
+ font-weight: 500;
+}
diff --git a/site/_tests/05-tracejam-saas/brief.md b/site/_tests/05-tracejam-saas/brief.md
new file mode 100644
index 0000000..4c6fe95
--- /dev/null
+++ b/site/_tests/05-tracejam-saas/brief.md
@@ -0,0 +1,43 @@
+# Test 05 — Tracejam (SaaS observability tool)
+
+## The prompt
+
+> "Build a landing page for Tracejam — a tracing/observability tool for distributed systems. Audience: SREs and platform engineers. Use case: try it / contact sales. Tone: technical."
+
+## Context gate — fully answered
+
+Audience, use, tone all explicit. No inference needed.
+
+## Domain inference
+
+`platform / tool / infra / dashboard / developer` → from the domain table: **Workbench / Bento Grid / Stat-Led** are reasonable picks.
+
+The skill picks **Bento Grid** because Tracejam has many surfaces (traces, metrics, alerts, logs) and Bento communicates "many entry points" the way Workbench would communicate "one thing, walked through". Workbench was the runner-up.
+
+## Theme
+
+The tempting default for a SaaS observability tool is **Midnight** (dark technical). But the skill resists: Midnight has been used elsewhere, and the brief says "technical" not "dark". Picking **Pastel** instead — post-Linear soft tech, low-chroma indigo accent, soft surfaces. The test is whether a Pastel page can still feel rigorous to an SRE; the answer is yes if the typography is exact.
+
+## Enrichment
+
+**E1 Demo Video — Clipped-Edge** archetype, but with a Tier-A pure-CSS dashboard mockup instead of real video. The mockup is a hand-built CSS-art trace waterfall (a flame chart) — it says "this is real software" without needing to ship a 4 MB video.
+
+The decision is *not* "embed a Loom". *Not* "use a stock video". *Not* "build a Lottie loop of moving bars". Pure CSS art is the right tier — the dashboard is geometric, the data are coloured rectangles, and CSS does that beautifully.
+
+## Macrostructure stamp
+
+```
+/* Hallmark · macrostructure: Bento Grid · F1 bento knobs: tiles=6, spans=irregular, accent=corner-only
+ * H7 hero: Demo Video Clipped-Edge · clip=right, aspect=16/10, frame=hairline
+ * theme: Pastel · accent: indigo ~3% · enrichment: tier-A CSS art mockup (flame chart trace waterfall)
+ * studied: no · context: explicit
+ */
+```
+
+## What the page does
+
+- Hero: clipped-edge browser-frame mockup containing a CSS-art trace waterfall (a flame chart of an HTTP request fanning out into ~20 spans across four services). Headline left, mockup right, mockup extends ~12 vw past the viewport edge.
+- Bento grid below: six asymmetric tiles, each one a feature with its own visual treatment (a numerical stat, a small CSS chart, a code snippet, a quote from a user, a tabular table of integrations, a single sentence)
+- Two CTAs: "Try it" (outlined chip) and "Talk to sales" (typographic link)
+- Footer: index columns
+- Soft 12 px radius on every card. Indigo accent at ~3 % footprint.
diff --git a/site/_tests/05-tracejam-saas/index.html b/site/_tests/05-tracejam-saas/index.html
new file mode 100644
index 0000000..0565d18
--- /dev/null
+++ b/site/_tests/05-tracejam-saas/index.html
@@ -0,0 +1,176 @@
+
+
+
+
+
+ Tracejam — distributed tracing that explains itself
+
+
+
+
+
+
+
+
+
+
Tracejam · v0.4 · for SREs
+
Distributed tracing that explains itself.
+
Open the trace, find the span that regressed, and read why — in plain text — without a glossary, a YAML diff, or a status-page hunt.
I help engineering organisations ship hard distributed-systems work — multi-region rollouts, payment graphs, eventually-consistent ledgers — without breaking the people doing the shipping. I write a lot, draw a lot of diagrams, and try not to ship a system the on-call rotation can't run on a Saturday.
+
Twelve years across Stripe, Monzo, and a small infra startup that didn't survive 2023. Currently consulting; selectively taking on three to four engagements per year.
+
+
+
+
Selected work
+
+
+ 2024–25
+ Designed and led a 14-month payments graph rewrite.From a single Postgres write path to a sharded, replay-safe ledger across three regions.
+ Fintech, 400 engineers
+
+
+
+ 2023
+ Set up the platform team's first SLO programme.Wrote the runbooks, ran the postmortems, retired the dashboard everyone hated.
+ Marketplace, 80 engineers
+
+
+
+ 2022
+ Migrated a 200-service monorepo from one CI to another.Without breaking a single deploy. The PR had 1,800 reviewers.
+ Infra startup, ~50 engineers
+
+
+
+ 2018–21
+ Built and ran the on-call programme at a B2B fintech, 0→200 engineers.Wrote the doc that's still pinned in their #incident channel.
+ Fintech, 0→200 engineers
+
+
+
+
Currently: finishing a long engagement on a multi-region ledger; writing a short book on running on-call as a team practice rather than a heroism contest.
+
+
+
+
+
+
+
diff --git a/site/_tests/06-anya-portfolio/style.css b/site/_tests/06-anya-portfolio/style.css
new file mode 100644
index 0000000..b4705a4
--- /dev/null
+++ b/site/_tests/06-anya-portfolio/style.css
@@ -0,0 +1,235 @@
+/* Hallmark · macrostructure: Long Document · H5 hero knobs: salutation=greeting, body=2 paragraphs, signoff=initials
+ * theme: Studio · accent: forest-green ~2% (a single mark)
+ * enrichment: none (typography only — restraint is the credibility signal)
+ * studied: no · context: skipped, inferred (personal / portfolio domain)
+ */
+
+@import url("https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;1,9..144,400;1,9..144,500&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500&display=swap");
+
+:root {
+ --paper: oklch(96.5% 0.014 95);
+ --paper-2: oklch(94% 0.016 95);
+ --rule: oklch(82% 0.012 90);
+ --rule-2: oklch(70% 0.010 90);
+ --muted: oklch(48% 0.010 95);
+ --neutral: oklch(34% 0.014 100);
+ --ink-2: oklch(22% 0.018 100);
+ --ink: oklch(13% 0.020 100);
+ --accent: oklch(46% 0.140 145);
+
+ --serif: "Fraunces", "Tiempos", ui-serif, Georgia, serif;
+ --body: "Geist", "Söhne", system-ui, sans-serif;
+ --mono: "Geist Mono", ui-monospace, monospace;
+
+ --space-xs: 0.5rem;
+ --space-sm: 0.75rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2.5rem;
+ --space-2xl: 4rem;
+ --space-3xl: 6.5rem;
+
+ --rule-hair: 0.5px;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+html {
+ font-family: var(--body);
+ font-size: 16px;
+ line-height: 1.6;
+ color: var(--ink-2);
+ background: var(--paper);
+ -webkit-font-smoothing: antialiased;
+}
+
+body {
+ min-height: 100dvh;
+ display: grid;
+ grid-template-rows: auto 1fr auto;
+ padding-inline: clamp(1.5rem, 7vw, 5rem);
+}
+
+/* ─── Top bar ─── */
+.top {
+ display: flex;
+ justify-content: space-between;
+ align-items: baseline;
+ padding-block: var(--space-lg);
+ border-block-end: var(--rule-hair) solid var(--rule);
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.08em;
+ color: var(--muted);
+ text-transform: uppercase;
+}
+.top .name { color: var(--ink); }
+.top .name::before {
+ content: "";
+ display: inline-block;
+ width: 6px;
+ height: 6px;
+ background: var(--accent);
+ margin-inline-end: 0.6em;
+ vertical-align: 1px;
+}
+
+/* ─── The letter ─── */
+.fold {
+ max-width: 56rem;
+ margin: 0 auto;
+ padding-block: var(--space-3xl) var(--space-2xl);
+ display: grid;
+ gap: var(--space-2xl);
+}
+
+.salutation {
+ font-family: var(--serif);
+ font-style: italic;
+ font-weight: 400;
+ font-size: clamp(2.5rem, 5vw + 1rem, 4.25rem);
+ font-variation-settings: "opsz" 144, "SOFT" 30;
+ line-height: 1.05;
+ letter-spacing: -0.02em;
+ color: var(--ink);
+ max-width: 16ch;
+}
+
+.salutation strong {
+ font-style: normal;
+ font-weight: 500;
+ background: linear-gradient(180deg, transparent 78%, color-mix(in oklch, var(--accent) 30%, transparent) 78%);
+ padding: 0 0.05em;
+}
+
+.letter {
+ display: grid;
+ gap: var(--space-md);
+ max-width: 38rem;
+}
+
+.letter p {
+ font-size: 1.0625rem;
+ line-height: 1.65;
+ color: var(--ink-2);
+}
+
+.letter em {
+ font-family: var(--serif);
+ font-style: italic;
+ color: var(--ink);
+}
+
+/* ─── Selected work — tabular ─── */
+.work {
+ display: grid;
+ gap: 0;
+}
+
+.work h2 {
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.16em;
+ text-transform: uppercase;
+ color: var(--muted);
+ font-weight: 400;
+ margin-block-end: var(--space-md);
+}
+
+.work__row {
+ display: grid;
+ grid-template-columns: 4rem 1fr 14rem;
+ gap: var(--space-md);
+ padding-block: var(--space-md);
+ border-block-start: var(--rule-hair) solid var(--rule);
+ align-items: baseline;
+ font-size: 0.9375rem;
+}
+
+.work__row:last-child { border-block-end: var(--rule-hair) solid var(--rule); }
+
+.work__year {
+ font-family: var(--mono);
+ font-size: 0.8125rem;
+ color: var(--muted);
+ letter-spacing: 0.04em;
+ font-variant-numeric: tabular-nums;
+}
+
+.work__what {
+ color: var(--ink);
+ font-weight: 500;
+}
+.work__what em {
+ font-family: var(--serif);
+ font-style: italic;
+ font-weight: 400;
+ color: var(--neutral);
+ display: block;
+ font-size: 0.9375rem;
+ margin-block-start: 0.15em;
+}
+
+.work__where {
+ font-family: var(--mono);
+ font-size: 0.78rem;
+ letter-spacing: 0.04em;
+ color: var(--muted);
+ text-align: right;
+}
+
+@media (max-width: 44rem) {
+ .work__row { grid-template-columns: 4rem 1fr; }
+ .work__where { grid-column: 1 / -1; text-align: left; padding-inline-start: calc(4rem + var(--space-md)); margin-block-start: -0.4em; }
+}
+
+/* ─── Currently + elsewhere ─── */
+.currently,
+.elsewhere {
+ font-family: var(--serif);
+ font-style: italic;
+ font-size: 1.125rem;
+ color: var(--ink-2);
+ max-width: 38rem;
+}
+
+.currently strong {
+ font-style: normal;
+ font-weight: 500;
+ color: var(--ink);
+}
+
+.elsewhere {
+ font-family: var(--body);
+ font-style: normal;
+ font-size: 0.9375rem;
+}
+
+.elsewhere a {
+ color: var(--ink);
+ text-decoration: none;
+ background-image: linear-gradient(var(--accent), var(--accent));
+ background-repeat: no-repeat;
+ background-position: 0 calc(100% - 1px);
+ background-size: 100% 1px;
+ padding-block-end: 0.1em;
+ transition: background-size 200ms cubic-bezier(0.16, 1, 0.3, 1);
+}
+.elsewhere a:hover { background-size: 100% 2px; }
+.elsewhere .sep { color: var(--rule-2); margin-inline: 0.6em; }
+
+/* ─── Footer ─── */
+footer {
+ padding-block: var(--space-lg);
+ border-block-start: var(--rule-hair) solid var(--rule);
+ font-family: var(--mono);
+ font-size: 0.75rem;
+ letter-spacing: 0.06em;
+ color: var(--muted);
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--space-md);
+}
+footer .ink { color: var(--ink); }
+footer .sep { color: var(--rule-2); }
diff --git a/site/_tests/README.md b/site/_tests/README.md
new file mode 100644
index 0000000..4d0cf01
--- /dev/null
+++ b/site/_tests/README.md
@@ -0,0 +1,88 @@
+# Hallmark — generation tests
+
+Six landing pages produced by exercising the Hallmark skill across contrasting briefs. The point: see what comes out *without* hand-holding the AI on theme, structure, or enrichment. Each test deliberately tests a different scenario.
+
+| # | Brief | Context given | Theme requested | What the skill picked |
+| --- | --- | --- | --- | --- |
+| 01 | Indie podcast `Tide`, no detail | **Skipped** ("you pick") | none | Quote-Led + Atelier + no enrichment |
+| 02 | Open-source CLI `Streampipe` for stream parsing | Full (devs / install + docs / technical) | **Terminal** (requested) | Workbench + Terminal + Tier-A CSS-art terminal mockup |
+| 03 | Artisan bakery `Maple Street Bread` | Full (locals / browse + visit / warm hand-set) | none | Long Document + Linen + Tier-B hand-built SVG loaf |
+| 04 | Manifesto for an environmental studio `Meridian` | Partial ("declarative, no flashy stuff") | none (implied) | Manifesto + Manifesto + no enrichment |
+| 05 | SaaS observability tool `Tracejam` | Full (SREs / try-or-talk-to-sales / technical) | none | Bento Grid + Pastel + E1 clipped-edge dashboard mockup |
+| 06 | Personal one-pager for `Anya` (software architect) | **Skipped** ("don't ask, just figure it out") | none | Long Document + Studio + no enrichment |
+
+Each folder contains:
+
+- **`brief.md`** — the verbatim prompt, what the skill asked / inferred, and the macrostructure stamp the page ships with
+- **`index.html`** — the rendered page (self-contained, no shared assets)
+- **`style.css`** — the page's tokens + components, with the Hallmark stamp at the top
+
+Open any one with `open site/_tests//index.html` or browse via the local dev server at `http://localhost:8765/_tests//`.
+
+## What this exercise was for
+
+Stress-testing the skill on briefs that range from "complete spec" to "you figure it out, I'm lazy". Specifically watching for:
+
+1. Does the skill default to the same shape twice across the six tests? → No two should share a macrostructure or hero archetype.
+2. Does the skill enrich every page even when it shouldn't? → Tests 01, 04, 06 should be typography-only.
+3. When the user skips the design-context gate, does the skill state its inferences in one sentence at the top? → Yes, see brief.md headers.
+4. Does the skill bend toward "Built for the modern team" voice when copy is left to it? → Each brief has its own voice; no template-soup.
+
+Findings and a priority list of skill improvements are at the bottom of this file, after the six test cases.
+
+---
+
+## Findings — what worked, what didn't, what to fix
+
+### What worked
+
+1. **Six different briefs produced six structurally different pages.** No two share a macrostructure, hero archetype, or footer voice. The page-shape variety the skill is built around held up under the test.
+2. **Three of six tests ship with no enrichment.** The skill correctly resisted the urge to add a Lottie / illustration / mockup to the podcast (typography-only is right for voice), the manifesto (a manifesto is not a marketing page), and the personal portfolio (restraint is the credibility signal). This is the test the *previous* anti-slop generation failed.
+3. **The two tests that reach for hand-built CSS art (Tracejam flame chart, bakery loaf) produced custom DOM — not Lottie.** The skill picked Tier-A or Tier-B from the enrichment hierarchy without asking, and the result feels designed, not pulled.
+4. **The skipped-context flow worked twice (01 podcast, 06 architect).** Both pages open with an inferred-context disclosure sentence at the top of `brief.md`, which is the documented pattern. The skill states what it inferred.
+5. **Type pairing held across all six.** No two tests share a font stack. Newsreader (1, 3), Geist Mono (2, 5), Inter Tight (4), Fraunces (6) each carry one page; pairing logic is theme-driven so this fell out naturally.
+6. **The clipped-edge mockup (test 5) was hand-built CSS, not a video file.** The skill resisted the temptation to ship "embed a Loom" — the trace waterfall is pure CSS bars on a percentage grid.
+
+### Friction points I hit while generating
+
+- **The "domain → trio" table covers most cases but not all.** The bakery is in the table; the manifesto is in the table; the personal portfolio is in the table. The SaaS tracing tool is *implicitly* in the table under "platform / tool / infra". The podcast is in the table. **But:** I had to combine "SaaS marketing" + "developer tool" mentally to land on Bento Grid for Tracejam — the skill could be more explicit about *which* of the three suggested macrostructures wins for a given sub-domain. (E.g., "platform/tool" → Workbench or Bento; pick Workbench when the brief says docs/walkthrough, pick Bento when the brief says try-or-talk-to-sales.)
+- **Theme picking is still by feel.** The skill has a strong rule that "the next theme can't be Specimen if the last one was Specimen" — but no rule like *"the next theme should be categorically different on at least one of: paper-band, display-style, accent-hue."* I avoided repeating themes here by deliberate intuition; a documented rule would help future runs.
+- **Copy generation bent toward "Built for the modern team" twice — and I had to course-correct.** Tracejam's first draft headline was *"Trace what matters."* — a near-template; I rewrote it to *"Distributed tracing that explains itself."* which is more specific. **The skill needs example copy fixtures per macrostructure** (Tier 3 in the existing roadmap) — without them, the model bends toward LLM-distribution copy.
+- **The `hero-enrichment.md` decision protocol is text-only — no concrete worked examples per domain.** I had to imagine what Tracejam's "Demo Video Clipped-Edge" looks like vs. "Mockup Split"; an in-file example for each enrichment archetype on a real page would speed this up.
+- **Within-archetype variation knobs work in theory but I leaned on the same defaults.** The two pages with footer-index (Tracejam, none of the others ended up there) and footer-inline (the podcast, the bakery, the architect) all converge on the same shape. A future run on the *same* footer archetype should pick *different* knobs — but the rule lives in the cookbook, not in muscle memory.
+- **Free fonts only got me so far.** The bakery wanted Tiempos Headline (paid, Klim); I substituted Newsreader. The Studio theme on Anya's portfolio wanted Tobias (paid); Fraunces is a strong understudy but not the same. The skill should explicitly call out free-vs-paid trade-offs with two-tier candidates per pairing.
+
+### Improvement list — priority order
+
+This is the punch list. Do these and the skill goes from "good" to "as good as a human-curated design.md gets in 2026".
+
+#### Tier 1 — Real holes (next session)
+
+1. **Per-archetype example copy fixtures.** For each of the 21 macrostructures, ship 2–3 example *opening-line copy fragments* in `references/macrostructures.md`. The model imitates them instead of bending to LLM distribution. Highest single payoff for output quality. Currently roadmap Tier 3.
+2. **Sub-domain refinement for the trio table.** Split "platform / tool / infra / dashboard / developer" into two rows: *docs/walkthrough* → Workbench / Long Doc; *try-or-talk-to-sales* → Bento / Stat-Led / Workbench. Same for "personal" (one-pager Letter vs. multi-page Long Doc).
+3. **A documented theme-diversification rule.** *"Across consecutive Hallmark outputs in this user's session/project, no two themes should share more than one of: paper-band, display-style, accent-hue."* Currently the rule is "don't repeat Specimen", which is tighter on one tail than it should be.
+4. **Free-vs-paid font trade-off in `typography.md`.** Each tone gets two pairings: "free baseline" and "paid upgrade if the user can pay". The bakery example would say: "Free: Newsreader + Geist + Geist Mono. Paid upgrade: Tiempos Headline + Söhne + Söhne Mono."
+5. **Worked examples in `hero-enrichment.md` per archetype.** A 5-line "what this looks like for X brief" under each E1–E8. Right now the descriptions are abstract; concrete worked examples accelerate generation.
+
+#### Tier 2 — Quality polish
+
+6. **A "different knobs" check in the slop test.** Question 34: *"If I used the same archetype as a previous Hallmark output (e.g., footer-inline twice), did I pick at least one different variation knob?"* Catches the template-soup-within-an-archetype risk this exercise surfaced.
+7. **More illustration recipes in `custom-craft.md`.** The bakery loaf was the only worked example. Add one for: a workflow diagram, a mascot, a small architectural diagram, a botanical accent. Each in 30–60 lines. The bakery loaf I generated above had room to be sharper — the recipes should show what *good* looks like at this scale.
+8. **A `references/copy.md` extension with non-LLM voice samples.** Three voices per tone (editorial / brutalist / soft / technical / luxury / playful / austere) with 5 example sentences each. Borrow from real sites (Klim, Linear, Apple, Tufte, Rauno, Frieze) — credit them, don't copy.
+9. **Mobile breakpoint discipline per archetype.** I caught this on test 5 (Tracejam): the clipped-edge mockup needed a 60rem media query to collapse to stacked. The cookbook entries should say *"on viewports below X, this archetype collapses to Y"* so it's automatic.
+10. **An in-skill check: did I write `aria-label` on every visual-only SVG?** I caught it manually for the bakery loaf and the trace waterfall, but a slop-test gate would make it automatic.
+
+#### Tier 3 — Long bet
+
+11. **Project-level memory beyond the CSS stamp.** Right now the skill reads the *latest* stamp in the project. A `.hallmark/log.json` per-project file (history of macrostructures + themes + briefs) would let the diversification rules see further back.
+12. **A "study + remix" combined verb.** `hallmark study + redesign` in one — extract DNA from a screenshot, then rebuild the user's content with that DNA. Today the user has to chain `study` then `redesign`; one verb would be tighter.
+13. **A real example gallery on the landing page.** These six tests should be linked from the main `site/index.html` as a "Generated by Hallmark" gallery, with one-line captions. Marketing the skill via the skill's outputs.
+14. **Auto-generated Open Graph cards per page.** Each test ships its own meta description, but the OG image is missing. A small Hallmark utility that generates an OG image per page from the macrostructure stamp + headline would close the loop.
+
+### What this means for the skill
+
+Hallmark is *good*. The structural variety position holds — six briefs, six different pages, no template repetition. The enrichment hierarchy works — three of six pages correctly choose to ship nothing visual, and the three that do enrich pick the right tier (custom-built, not Lottie).
+
+The remaining gap is **copy voice** and **theme-pick discipline**. The slop test catches *visual* tells well; it doesn't yet catch *prose* tells (like "Built for the modern team" headlines). And the diversification rules are tight on one axis (no Specimen fall-through) but loose on the rest.
+
+Tier 1 of this list is the next session's work.