Fix · study handoff uses extracted DNA as the system, not a catalog theme

When the user ran `study <URL>` and then said "build it", Hallmark fell back to a catalog theme (the "closest cousin" hint in the diagnosis) instead of using the studied DNA — paper/accent/fonts/macrostructure from the source were discarded.

- study.md: rewrote both diagnosis templates and the worked example. The "closest catalog theme" line is now framed as an explicit pivot option ("just say 'use X instead'"), not a recommendation. The "build it" handoff explicitly uses the studied DNA as the system.
- SKILL.md § 2.6: new Condition 0 (highest priority) — when a study diagnosis was emitted earlier in the conversation and the user asks to build from it ("build it" / "make it" / "use this DNA"), skip catalog/custom dispatch entirely. The DNA's tokens, macrostructure, and archetypes become the locked system. Diversification suspended for the build. Pivot phrases ("use Linen instead" / "ignore the DNA") route back to normal dispatch.
- SKILL.md Step 6: stamp's `theme:` field is `studied-DNA (source: <URL or image>)` with inline OKLCH/font values for studied builds.
- slop-test.md: new gate 69 auto-fails any build that names a catalog theme in its stamp when a recent study exists and the user didn't explicitly pivot.
- Gate count bumped 68 → 69 in SKILL.md + preview-examples.md.
This commit is contained in:
Youssef
2026-05-18 15:37:09 +01:00
parent f5d5c075a2
commit ab5f84ee9d
4 changed files with 31 additions and 18 deletions
+7 -6
View File
@@ -319,10 +319,11 @@ Then the theme rotation, on the next line:
The rotation block keeps the user inside the discipline without making them read the rules. Skip it and the user starts thinking the diversification is theatre.
### 2.6. Theme route — catalog or custom
### 2.6. Theme route — studied-DNA, catalog, or custom
By the time you reach this step, one of three things is true:
By the time you reach this step, one of four things is true:
0. **A `study` diagnosis was emitted earlier in this conversation and the user is asking to build from it** (phrases: *"build it"*, *"make it"*, *"use this DNA"*, *"build with this"* — immediately following the diagnosis) → theme route is **studied-DNA**. **Skip catalog/custom dispatch entirely.** The studied paper OKLCH, accent OKLCH, type roles (with named candidates), macrostructure, and nav/footer archetypes from the diagnosis become the locked system for this build. Diversification is suspended — you're following an external DNA, not rotating the catalog. The Step 6 stamp records `theme: studied-DNA (source: <URL or image>)` plus the actual OKLCH/font values inline. **If the user later pivots with phrases like *"use Linen instead"* / *"ignore the DNA"* / *"rotate to a different theme"*,** route back to the normal dispatch below and resume diversification. Continue to Step 3.
1. **The user named custom** (because they said so, or because Step 1's signal detection fired and they confirmed) → load [`references/custom-theme.md`](references/custom-theme.md), ask the **one** follow-up (vibe in 48 words + optional anchor colour), construct the OKLCH palette + free-font pairing, compute the three axis values (paper-band / display-style / accent-hue), then continue to Step 3.
2. **The user named catalog** (or implicitly accepted it by not naming custom) → pick one of the 22 named themes per the diversification rule above. Existing flow — continue to Step 3.
3. **Neither was discussed** (Step 1's signals didn't fire — vanilla brief) → default to **catalog**. Do not pause. Do not ask. Continue to Step 3.
@@ -403,7 +404,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
- **Enrichment** · none (typography only)
- **Sections** · Hero · Logos · Stats · Features · Testimonials · Pricing · FAQ · CTA · Footer
- **Motion** · counter · pricing-lift · pulse-once
- **Slop test** · 68 / 68 ✓ (run after Build)
- **Slop test** · 69 / 69 ✓ (run after Build)
- **Diversification** · differs from Linen on display style + accent hue
```
@@ -414,7 +415,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
3. **Enrichment** — the chosen archetype + tier, or *none (typography only)*.
4. **Sections** — section names separated by ` · `, in DOM order.
5. **Motion** — microinteraction primitives separated by ` · `, or *none — typography only*. Always under three primitives per the [`microinteractions.md`](references/microinteractions.md) hard rules.
6. **Slop test** — `68 / 68` if all gates pass, or `N / 68 — fails: <gate numbers>` if any are open. Run the slop test BEFORE writing this row; the slop test is Step 7.
6. **Slop test** — `69 / 69` if all gates pass, or `N / 69 — fails: <gate numbers>` if any are open. Run the slop test BEFORE writing this row; the slop test is Step 7.
7. **Diversification** *(optional, only when `.hallmark/log.json` has prior entries)* — what axes differ vs the previous run.
**Then one quiet CTA line, italicised, after the bullets:**
@@ -445,7 +446,7 @@ Always:
- Include `:focus-visible` with a visible ring at ≥3:1 contrast. **Never animate the ring's appearance** — it must show instantly on focus.
- 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 `<style>` if inline) MUST be a comment of the form: `/* Hallmark · macrostructure: <name> · tone: <tone> · anchor hue: <hue> */`. This stamp is the durable record of what you chose. The next time Hallmark runs in this project, it reads the stamp and picks a *different* macrostructure. **For custom themes**, the stamp also carries the vibe, paper + accent OKLCH values, the chosen display + body fonts, and the three diversification axes — the full multi-line format is in [`custom-theme.md`](references/custom-theme.md) § E.
- **Stamp the output.** The first non-empty line of the produced CSS file (or the top of `<style>` if inline) MUST be a comment of the form: `/* Hallmark · macrostructure: <name> · tone: <tone> · anchor hue: <hue> */`. This stamp is the durable record of what you chose. The next time Hallmark runs in this project, it reads the stamp and picks a *different* macrostructure. **For custom themes**, the stamp also carries the vibe, paper + accent OKLCH values, the chosen display + body fonts, and the three diversification axes — the full multi-line format is in [`custom-theme.md`](references/custom-theme.md) § E. **For studied-DNA builds** (Step 2.6 Condition 0 routed here from a `study` diagnosis), the stamp's `theme:` field is `studied-DNA (source: <URL or "image">)` followed by the paper OKLCH, accent OKLCH, and display + body fonts pulled directly from the diagnosis — not a catalog theme name. Diversification stays suspended for the run; the log entry below records `theme: studied-DNA` so Step 2.5 on the next run knows not to rotate against it.
- **Append to project memory.** After you write the stamp, update (or create) `.hallmark/log.json` at the project root. Append a new entry at the **front** of the array: `{ "date": "<YYYY-MM-DD>", "macrostructure": "<name>", "theme": "<name>", "enrichment": "<E# name or 'none'>", "brief": "<one-line summary>" }`. **Custom entries** also carry `"theme": "custom"` plus `"theme_axes": "<paper-band> / <display-style> / <accent-hue>"` and an optional `"vibe": "<48 words>"` — see [`custom-theme.md`](references/custom-theme.md) § F. Trim the file to the last 20 entries (rotate the oldest off). Create `.hallmark/` and the file if they don't exist; respect any existing `.gitignore` (the user may or may not want this committed). This file is what Step 2.5 reads on the next run.
- **Always emit `tokens.css`.** After writing the page CSS, also write `tokens.css` at the project root containing every `--color-*`, `--font-*`, `--space-*`, `--text-*`, `--ease-*`, `--dur-*`, `--rule-*`, and `--radius-*` token used in the build. The page CSS imports `tokens.css` (or, on framework projects, the project's existing entry-point includes it) — the page CSS must reference tokens by name, never inline raw values. Even single-page builds get a `tokens.css`. This is what makes the design system portable to the next project. Load [`export-formats.md`](references/export-formats.md) at this point only when the project warrants additional formats — see below.
- **Multi-format exports on `design.md` projects.** If a `design.md` exists at the project root (a system-managed project), append all four export formats — `tokens.css`, Tailwind v4 `@theme`, DTCG `tokens.json`, shadcn/ui CSS variables — into `design.md`'s `## Exports` section. Load [`export-formats.md`](references/export-formats.md) for the canonical mapping from Hallmark tokens to each format. Single-page projects skip this step (they get only `tokens.css`).
@@ -453,7 +454,7 @@ Always:
### 7. The slop test
Before handing back, run the output through the 68-gate slop test in [`references/slop-test.md`](references/slop-test.md). Every answer must be **no**. Load that file at this step (not earlier — it isn't needed until handoff). The active genre matters: some gates are universal, some are genre-scoped (atmospheric loosens the radial-bloom gate; modern-minimal loosens the zero-chroma neutral gate; etc.). The full per-genre overrides are listed inline in `slop-test.md`.
Before handing back, run the output through the 69-gate slop test in [`references/slop-test.md`](references/slop-test.md). Every answer must be **no**. Load that file at this step (not earlier — it isn't needed until handoff). The active genre matters: some gates are universal, some are genre-scoped (atmospheric loosens the radial-bloom gate; modern-minimal loosens the zero-chroma neutral gate; etc.). The full per-genre overrides are listed inline in `slop-test.md`.
Run the slop test BEFORE writing the Slop test row in the Step 5 preview block — that row reflects the actual outcome of this step.
+4 -4
View File
@@ -12,7 +12,7 @@ Four sample Step 5 preview blocks for the model to imitate, varied across macros
> - **Enrichment** · Tier-B hand-built SVG (a 60-line coffee bean with `@property --rise` 6 s breathing-loop)
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
> - **Motion** · breathing-loop on bean only (respects `prefers-reduced-motion`)
> - **Slop test** · 68 / 68
> - **Slop test** · 69 / 69
> - **Diversification** · first run for this project
*Bento Grid (SaaS, motion-on):*
@@ -23,7 +23,7 @@ Four sample Step 5 preview blocks for the model to imitate, varied across macros
> - **Enrichment** · E1 Clipped-Edge Demo Video, Tier-A CSS-art trace waterfall
> - **Sections** · Hero · 6-tile Bento (stat · sparkline · quote · code · integrations · spotlight) · Index Footer
> - **Motion** · counter · pricing-lift · CSS marquee on integrations strip
> - **Slop test** · 68 / 68
> - **Slop test** · 69 / 69
> - **Diversification** · differs from Plain on paper hue (light-cool vs pure-white) + accent (indigo vs ink-blue)
*Manifesto (declarative, no enrichment):*
@@ -34,7 +34,7 @@ Four sample Step 5 preview blocks for the model to imitate, varied across macros
> - **Enrichment** · none (typography only — voice carries the brand)
> - **Sections** · Masthead · Title · Five Declarations · Bleed Band · What We Refuse · Working Rules · Practice · Reading · Colophon
> - **Motion** · none — typography only
> - **Slop test** · 68 / 68
> - **Slop test** · 69 / 69
> - **Diversification** · differs from Linen on paper band (dark vs light) + display style (display-heavy vs geometric-sans)
*Custom (Coffeebox archival café):*
@@ -45,5 +45,5 @@ Four sample Step 5 preview blocks for the model to imitate, varied across macros
> - **Enrichment** · Tier-A pure-CSS coffee bean (60-line SVG, breathing-loop optional)
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
> - **Motion** · breathing-loop on bean (with reduced-motion fallback)
> - **Slop test** · 68 / 68
> - **Slop test** · 69 / 69
> - **Diversification** · custom axes: light / italic-serif / chromatic-terracotta — differs from previous catalog Linen on accent hue + display style
+3 -1
View File
@@ -196,7 +196,9 @@ Universal. Every emitted page must render flawlessly at 320 px, 375 px, 414 px,
68. **Sticky element at `top: 0` below a sticky page-level nav → bleed.** Does the artifact declare `position: sticky; top: 0;` on any element OTHER than the page's top-level nav / banner / header, when a sticky `<header>` / `<nav>` / `.banner` also exists at `top: 0` (i.e. there are two sticky-at-top-0 elements on the page)? Auto-fail. Both stick to the viewport top during scroll and overlap; the deeper-in-DOM element paints over the nav (visible as a "section header bleeding into the nav bar" glitch). Fix: define a `--banner-height` token (~4464 px depending on nav design) and offset every secondary sticky to `top: var(--banner-height)`, so it docks **beneath** the nav. Also give the nav a higher z-index than in-page sticky elements — split `--z-sticky` (in-page, e.g. 200) from `--z-sticky-nav` (top nav, e.g. 300) so the nav always out-paints when sticky boxes momentarily overlap. This gate fires only when the page actually has sticky elements (S3 sticky-pinned section heads, F2 sticky-scroll feature stacks, sticky tables-of-contents); pages without sticky behaviour pass trivially.
The CSS stamp at Step 6 records mobile pass alongside contrast: `· mobile: pass (36, 59, 6168)`.
69. **Studied DNA discarded for a catalog theme.** Did a `study` diagnosis emit earlier in the conversation, AND does the build's CSS stamp's `theme:` field name a catalog theme (Specimen, Atelier, Brutal, Salon, Newsprint, Linen, Studio, Manifesto, Terminal, Midnight, Almanac, Garden, Quiet, Riso, Sport, Bloom, Coral, Violet, Aurora, Halo, Plume, Editorial) rather than `studied-DNA (source: ...)` — without the user having explicitly pivoted ("use Linen instead", "ignore the DNA", "rotate to a different theme")? Auto-fail. The studied DNA was meant to be the system (SKILL.md § 2.6 Condition 0); defaulting back to catalog is the attractor pull. Fix: re-emit using the studied DNA's tokens directly (paper OKLCH, accent OKLCH, named candidate fonts, macrostructure, archetypes) and update the stamp to `theme: studied-DNA (source: <URL or image>)` with the inline values. This gate is trivially passed when no recent study exists in conversation scope.
The CSS stamp at Step 6 records mobile pass alongside contrast: `· mobile: pass (36, 59, 6169)`.
---
+17 -7
View File
@@ -267,8 +267,11 @@ Anti-patterns I'd skip: [list anything from anti-patterns.md visible in
the screenshot — bouncy hovers, transition-all, three-feature grid, etc.
If there are none, say so.]
If you adopt this DNA, the closest theme in the catalog is [theme name].
That's a candidate, not a requirement — your content might point elsewhere.
If you say **build it**, I'll use the extracted DNA as the system — the
paper, accent, type roles, macrostructure, and nav/footer above become
the build's tokens. Catalog themes are suspended for that build. If
you'd rather pivot to a catalog cousin afterwards, the closest is
[theme name] — just say *"use [theme name] instead"*.
Want me to build with this DNA, or change one axis first?
@@ -299,8 +302,11 @@ transition-all on .card, hover-scale on buttons — or "none"].
Rhythm — density and asymmetry — I can't judge from the HTML alone. If
those matter, send a screenshot as well and I'll add a rhythm pass.
If you adopt this DNA, the closest theme in the catalog is [theme name].
That's a candidate, not a requirement — your content might point elsewhere.
If you say **build it**, I'll use the extracted DNA as the system — the
paper, accent, type roles, macrostructure, and nav/footer above become
the build's tokens. Catalog themes are suspended for that build. If
you'd rather pivot to a catalog cousin afterwards, the closest is
[theme name] — just say *"use [theme name] instead"*.
Want me to build with this DNA, or change one axis first?
@@ -365,19 +371,23 @@ The "Want me to build" line is the **confirmation question** for code generation
>
> Anti-patterns I'd skip: nothing from this screenshot stands out as carry-over risk. The reference is clean.
>
> If you adopt this DNA, the closest theme in the catalog is **Studio** (Instrument Serif italic display + Geist body + forest-green accent). Note: the screenshot's accent is neutral; Studio uses a small green mark — if you want neutral, I can desaturate the accent in the build.
> If you say **build it**, I'll use this DNA as the system — warm cream paper, neutral ink-on-paper accent, italic editorial serif + neutral grotesque + monospace, Split Studio macrostructure, H2 hero + Ft3 footer. Catalog themes are suspended for the build. If you'd rather pivot to a catalog cousin after, the closest is **Studio** (Instrument Serif + Geist + small green accent) — just say *"use Studio instead"*.
>
> Want me to build with this DNA, or change one axis first?
**If the user says "build it":** the skill picks **Studio**, picks **H2-Split** for the hero, fills the pitch with content from the user's brief (a feature/proof block — F4 Step sequence, say), keeps the Ft3 footer, stamps:
**If the user says "build it":** the skill builds with the **studied DNA as the system, not a catalog theme**. Paper, accent, type roles, macrostructure, and archetypes from the diagnosis become the tokens directly. Catalog rotation is suspended for this build (see SKILL.md § 2.6 Condition 0). The stamp records `theme: studied-DNA` with the source URL or image tag plus the actual OKLCH/font values inline:
```css
/* Hallmark · macrostructure: Split Studio · H2 hero knobs: ratio=6/6, right=proof, divider=negative-space
* Ft3 footer knobs: cols=4, heading=mono · theme: Studio · accent: neutral (override from default green)
* Ft3 footer knobs: cols=4, heading=mono
* theme: studied-DNA (source: image) · paper oklch(95% 0.012 80) · accent neutral (ink-on-paper)
* display: italic editorial serif (Instrument Serif candidate) · body: neutral grotesque (Geist candidate) · label: mono (Geist Mono)
* studied: yes · DNA-source: user reference (described as own work)
*/
```
**If the user instead says "build it with Studio":** the DNA hands the macrostructure + archetypes to the build but the catalog theme **Studio** supplies the tokens (Instrument Serif + Geist + forest-green accent). This is the pivot path — explicit only.
**If the user says "change the macrostructure":** offer two alternatives from the same family — say, Bento Grid (modular feature-led) or Long Document (prose-led). Whichever the user picks becomes the new macrostructure; the rest of the DNA carries.
---