diff --git a/README.md b/README.md
index ca9b7a4..964d31c 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ The differentiator: Hallmark insists on **structural variety**, not just visual
## What's inside
-- **[`SKILL.md`](skill/SKILL.md)** — the routing file. Design flow, slop test (33 questions), output contract.
+- **[`SKILL.md`](skill/SKILL.md)** — the routing file. Design flow (six steps, including `Step 2.5 · Check project memory` reading `.hallmark/log.json`), slop test (35 questions), output contract.
- **[`references/`](skill/references/)** — sixteen short, opinionated rule files: typography, colour, layout, motion, microinteractions, interaction-and-states, responsive, copy, anti-patterns, the 21 named macrostructures, the 36 component archetypes with variation knobs, the 6 primitive structure axes, the vision-extraction protocol for `study`, and three new files for hero work — `hero-enrichment.md` (when to add visuals to a hero, plus eight enrichment archetypes), `custom-craft.md` (how to hand-build CSS art, SVG, declarative animation, JS-driven motion, with Lottie demoted to last resort), and `assets.md` (sourcing canon for icons, brand logos, generated illustration via Nanobanana / Recraft, library illustration, app mockups, hero video, photography, abstract backgrounds).
- **[`site/`](site/)** — a self-demonstrating landing page. Hand-written HTML + CSS + ES module, no framework, no build step. **Sixteen themes** — Specimen, Newsprint, Atelier, Garden, Salon, Linen, Almanac, Midnight, Terminal, Brutal, Manifesto, Sport, Studio, Pastel, Riso, **Quiet** — that swap not just colour and typography but the page's hero archetype and footer archetype. Switching themes literally rebuilds the page.
- **[`ROADMAP.md`](ROADMAP.md)** — Tier 1, 2, 3 work plus an explicit "things to *not* do" list.
@@ -60,7 +60,10 @@ Press `T` to cycle themes, `R` for random, `?theme=studio` for a shareable link.
- **Macrostructures over axes.** Pick one of 21 named whole-page shapes wholesale; the macrostructure stamp lives in the CSS comment, so the next Hallmark run picks something different.
- **Within-archetype variation.** Two Bento Grids should not be twins; each archetype has 2–3 picked-per-output knobs.
- **Microinteractions as discipline.** Silent success over celebratory toasts. Optimistic update + Undo over confirm dialogs. Hover delay 800 ms, focus delay 0 ms.
-- **A 33-gate slop test** runs before every output. One yes fails the build.
+- **A 35-gate slop test** runs before every output. One yes fails the build. New gates 34 (different-knobs check across runs) and 35 (aria-label / aria-hidden on every visual-only SVG / canvas / div).
+- **Project memory.** A per-project `.hallmark/log.json` records each run's macrostructure + theme + enrichment + brief summary. The skill reads the last 3–5 entries before picking, and writes a new entry after each build, so consecutive Hallmark outputs in the same project don't repeat shapes or themes.
+- **Theme-diversification rule.** Two consecutive themes must differ on at least one of three axes: paper band (dark / mid / light), display style (italic-serif / roman-serif / geometric-sans / mono / display-condensed-italic / display-heavy / system-native / risograph), accent hue (warm / cool / neutral / chromatic). Specimen-fall-through is no longer the only diversification check.
+- **Voice fixtures over LLM defaults.** Each of the 21 macrostructures ships with 2–3 example opening lines from real designer-engineer sites (Pentagram, Klim, Linear, Are.na, Resend, Lynn Fisher, Rauno Freiberg, etc.). Each of seven tones in `copy.md` has three voice patterns × five sample sentences. "Built for the modern team" is in the banned-phrases list.
- **Hero enrichment is opt-in, not a default.** A typographic-only hero is always acceptable. When enrichment is right, the skill picks from a six-tier hierarchy: typography only → custom-built CSS art → hand-built SVG → generated illustration (Nanobanana / Recraft) → library + customise → Lottie (last resort).
- **`study` extracts DNA, not pixels.** Vision-extraction with refusal heuristics, type-role vocabulary (no font ID guessing), and a confirmation step before any code.
diff --git a/site/css/components.css b/site/css/components.css
index 5aa2d8a..f5a1df4 100644
--- a/site/css/components.css
+++ b/site/css/components.css
@@ -1638,6 +1638,166 @@
[data-theme="quiet"] .hero--clipped .hero__mock { display: none; }
[data-theme="quiet"] .hero--clipped { grid-template-columns: 1fr; }
+/* ───────────── EXAMPLE GALLERY ─────────────
+ Cards link to the six self-contained test pages under site/_tests/.
+ The cards inherit the active theme's --radius-card, --rule-card, and
+ --shadow-card so switching themes restyles them along with everything else. */
+
+.examples__intro,
+.examples__outro {
+ font-family: var(--font-serif);
+ font-style: italic;
+ font-size: var(--text-md);
+ line-height: var(--lh-snug);
+ color: var(--color-ink-2);
+ max-width: 56ch;
+ margin-block-end: var(--space-2xl);
+}
+
+.examples__outro {
+ margin-block: var(--space-xl) 0;
+}
+
+.examples__intro code {
+ font-family: var(--font-mono);
+ font-style: normal;
+ font-size: 0.875em;
+ background: var(--color-paper-2);
+ padding: 0.1em 0.4em;
+ border-radius: var(--radius-input, 0);
+ border: var(--rule-hair) solid var(--color-rule);
+ color: var(--color-ink);
+}
+
+[data-theme="brutal"] .examples__intro,
+[data-theme="manifesto"] .examples__intro,
+[data-theme="terminal"] .examples__intro,
+[data-theme="sport"] .examples__intro,
+[data-theme="almanac"] .examples__intro,
+[data-theme="brutal"] .examples__outro,
+[data-theme="manifesto"] .examples__outro,
+[data-theme="terminal"] .examples__outro,
+[data-theme="sport"] .examples__outro,
+[data-theme="almanac"] .examples__outro {
+ font-family: var(--font-body);
+ font-style: normal;
+}
+
+.gallery {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--space-lg);
+}
+
+@media (max-width: 60rem) {
+ .gallery { grid-template-columns: 1fr; }
+}
+
+.gallery__item {
+ display: grid;
+ grid-template-areas:
+ "num name"
+ "num shape"
+ "num desc"
+ "num open";
+ grid-template-columns: 4rem 1fr;
+ gap: 0 var(--space-md);
+ padding: var(--space-lg);
+ text-decoration: none;
+ color: inherit;
+ background: var(--color-paper);
+ border: var(--rule-card, 1px) solid var(--color-rule);
+ border-radius: var(--radius-card, 0);
+ box-shadow: var(--shadow-card, none);
+ transition: transform 100ms var(--ease-out),
+ border-color var(--dur-micro) var(--ease-out),
+ box-shadow var(--dur-short) var(--ease-out);
+ position: relative;
+}
+
+@media (hover: hover) and (pointer: fine) {
+ .gallery__item:hover {
+ border-color: var(--color-ink);
+ transform: translateY(-1px);
+ }
+}
+
+.gallery__item:focus-visible {
+ outline: 2px solid var(--color-focus);
+ outline-offset: 3px;
+}
+
+.gallery__num {
+ grid-area: num;
+ font-family: var(--font-label);
+ font-size: var(--text-sm);
+ letter-spacing: var(--tracking-label);
+ color: var(--color-muted);
+ align-self: start;
+ font-feature-settings: "tnum";
+}
+
+.gallery__name {
+ grid-area: name;
+ font-family: var(--font-display);
+ font-weight: var(--display-weight, 500);
+ font-style: var(--display-style, normal);
+ font-size: var(--text-xl);
+ letter-spacing: var(--tracking-tight);
+ color: var(--color-ink);
+ line-height: 1.05;
+ font-optical-sizing: auto;
+}
+
+.gallery__shape {
+ grid-area: shape;
+ font-family: var(--font-mono);
+ font-size: var(--text-xs);
+ letter-spacing: 0.04em;
+ color: var(--color-accent);
+ margin-block-start: 0.4em;
+}
+
+.gallery__desc {
+ grid-area: desc;
+ font-family: var(--font-body);
+ font-size: var(--text-sm);
+ color: var(--color-ink-2);
+ line-height: var(--lh-snug);
+ margin-block-start: var(--space-sm);
+ max-width: 36ch;
+}
+
+.gallery__open {
+ grid-area: open;
+ font-family: var(--font-label);
+ font-size: var(--text-xs);
+ letter-spacing: var(--tracking-label);
+ color: var(--color-muted);
+ margin-block-start: var(--space-md);
+ align-self: end;
+ justify-self: start;
+ text-transform: uppercase;
+ transition: color var(--dur-micro) var(--ease-out),
+ transform var(--dur-short) var(--ease-out);
+}
+
+.gallery__item:hover .gallery__open {
+ color: var(--color-ink);
+ transform: translateX(2px);
+}
+
+[data-theme="riso"] .gallery__name,
+[data-theme="brutal"] .gallery__name,
+[data-theme="manifesto"] .gallery__name,
+[data-theme="sport"] .gallery__name {
+ text-transform: uppercase;
+}
+
+[data-theme="riso"] .gallery__name {
+ text-transform: lowercase;
+}
+
/* ───────────── SPORT — section title fix ─────────────
The italic display + tight tracking + uppercase + weight 700
produced cramped, almost-touching letterforms. Loosen the
diff --git a/site/index.html b/site/index.html
index 9e18a05..65f582c 100644
--- a/site/index.html
+++ b/site/index.html
@@ -403,8 +403,76 @@
-
-
+
+
+
+
+ 07⁄Examples
+
+
+ Six pages, six different shapes.
+
+
+
+ Six landing pages produced by exercising the skill across contrasting briefs. Each page is its own self-contained HTML + CSS — no shared theme, no shared layout. Every one carries a /* Hallmark · macrostructure: … */ stamp at the top of its CSS.
+
+
+
+ Findings + improvement list at site/_tests/.
+
+
+
+
diff --git a/skill/SKILL.md b/skill/SKILL.md
index e7b9169..6dee6ca 100644
--- a/skill/SKILL.md
+++ b/skill/SKILL.md
@@ -1,7 +1,7 @@
---
name: hallmark
description: Use this skill when the user asks to design, build, redesign, audit, refine, or study a UI, web page, landing page, dashboard, component, or interface — or when they ask to make something "feel less AI-generated." Hallmark forces intentional design decisions (typography, color, layout, motion, interaction, structure) and refuses to default to the generic AI-UI template. Trigger phrases include "design a", "build a landing page", "make a dashboard", "redesign this site", "redesign the page", "refine this UI", "audit this design", "this looks AI-generated", "fix the design", "polish this", "give this a different look", and any request that will produce HTML / CSS / JSX / Tailwind output. **Also trigger when the user attaches a screenshot of a design they admire** — that is the `hallmark study` verb (extracts design DNA, never pixel-clones).
-version: 0.4.0
+version: 0.5.0
---
# Hallmark
@@ -65,12 +65,43 @@ Before loading any visual ruleset, **pick one of the twenty-one named macrostruc
2. If you have produced any other Hallmark output for this user in this session, your pick must be a different macrostructure than the last one.
3. **The Specimen macrostructure (numbered left-margin labels + huge serif + asymmetric spans + typographic CTA) is no longer a default.** Reach for it only when the brief is explicitly editorial, foundry-adjacent, or the user has named it.
-**State your pick.** Before writing any code, say "Macrostructure: ." in plain text. This is a deliberate accountability step — picking on the page (not in your head) prevents the default-attractor sameness that kept the skill emitting Specimen output.
+**Theme-diversification rule (mandatory).** Picking a different macrostructure isn't enough on its own — two consecutive Hallmark outputs can share a theme even if their structures differ, and the result reads as repetition. Two consecutive themes must differ on **at least one** of three axes:
+
+- **Paper band** — dark (L < 30 %) / mid (30–85 %) / light (> 85 %), per the theme's `--color-paper` lightness
+- **Display style** — italic-serif (Specimen, Studio, Atelier) / roman-serif (Newsprint, Salon, Linen) / geometric-sans (Pastel, Manifesto) / mono (Terminal) / display-condensed-italic (Sport) / display-heavy (Brutal) / system-native (Quiet) / risograph-bold (Riso)
+- **Accent hue** — warm (red / orange / amber: 10–60°) / cool (blue / indigo / cyan: 200–300°) / neutral (no chromatic accent: Quiet) / chromatic-other (green: Studio · sage: Garden · phosphor: Terminal)
+
+If the previous output was Specimen (light · italic-serif · warm), the next can be Studio (light · italic-serif · chromatic-green) — the *accent hue* differs. But the next can't be Salon (light · roman-serif · warm) which only differs on display style and shares both paper band and accent — pick a more distant theme.
+
+The per-theme axis values live as comments at the top of each theme's tokens block in [`site/css/tokens.css`](../site/css/tokens.css). When in doubt, name your candidate theme out loud and identify its three axis values; if two of three match the previous output, redirect.
+
+**State your pick.** Before writing any code, say "Macrostructure: . Theme: . Differs from the last on: ." in plain text. This is a deliberate accountability step — picking on the page (not in your head) prevents the default-attractor sameness that kept the skill emitting Specimen output.
If the brief is genuinely vague (no theme, no tone), do **not** default. Offer the user three macrostructures from *categorically different* groups (e.g. one grid-led like Bento, one document-led like Long Document, one poster-led like Manifesto). Three concrete choices, not seven abstract tones.
The macrostructure picks five of the six structural axes for you; you only need to pick the reveal yourself. The deeper axis catalogue is still in [`references/structure.md`](references/structure.md) when you need to deviate from the macrostructure's defaults.
+### 2.5. Check project memory
+
+If the project has a `.hallmark/log.json` file (created by previous Hallmark runs), **read it before** picking the macrostructure or theme. The schema is a JSON array, newest entry first:
+
+```json
+[
+ { "date": "2026-04-30", "macrostructure": "Bento Grid", "theme": "Pastel", "enrichment": "E1 clipped-edge", "brief": "Tracejam · SaaS observability" },
+ { "date": "2026-04-28", "macrostructure": "Long Document","theme": "Linen", "enrichment": "E5 hand-built SVG", "brief": "Maple Street Bread · bakery" },
+ { "date": "2026-04-25", "macrostructure": "Manifesto", "theme": "Manifesto","enrichment": "none", "brief": "Meridian · studio manifesto" }
+]
+```
+
+Use the **last 3–5 entries** to inform diversification:
+- Your macrostructure pick must not match any of the last three.
+- Your theme pick must differ from the last on at least one axis (see the theme-diversification rule above).
+- Your enrichment pick should not be the same enrichment archetype as the last (`E1 clipped` twice in a row reads as templated, even with different content).
+
+If the file doesn't exist, this is the first Hallmark run for this project — no constraint, but **you'll create the file in Step 5**.
+
+If the project has a CSS stamp but no `log.json`, infer one entry from the stamp and proceed.
+
### 3. Load the visual ruleset
The non-negotiables live in [`references/`](references/). Read only what you need:
@@ -121,10 +152,11 @@ Always:
- For each interaction in the output (button, input, modal, toast, drag, copy, etc.), apply the recipe in [`microinteractions.md`](references/microinteractions.md). Pick *silent success* over celebratory toasts. Pick *optimistic update + Undo* over confirmation dialogs. Pick *delay 800ms* on hover tooltips and *0ms* on focus tooltips.
- Cut motion before adding it. Most pages have too much, not too little. If removing an animation wouldn't lose the user information, remove it.
- **Stamp the output.** The first non-empty line of the produced CSS file (or the top of `