mirror of
https://github.com/Nutlope/hallmark.git
synced 2026-08-14 12:35:33 +02:00
Study · accept URL input alongside screenshots
URL mode reads HTML/CSS via WebFetch — names exact fonts and exact colour values; trades the rhythm pass for everything else getting more accurate. Auto-refuses template-marketplace URLs; falls back to asking for a screenshot if the URL is auth-walled or an SPA shell. Also drops a stale external reference from ROADMAP. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
422065f77a
commit
1cfcc89a06
+1
-3
@@ -18,8 +18,6 @@ A forward-looking plan for what to build next, drawn from the gaps the latest re
|
||||
|
||||
**Status now.** Hallmark produces code. It does not produce a portable design spec.
|
||||
|
||||
**Context from research.** [VoltAgent's `awesome-design-md`](https://github.com/VoltAgent/awesome-design-md) hit 35K stars in 10 days — fastest growing "awesome" list in GitHub history. DESIGN.md is becoming the lingua franca between humans and AI agents for design systems.
|
||||
|
||||
**Build.** When Hallmark generates new work, also emit a `DESIGN.md` in the project root containing: chosen tone, palette tokens (with OKLCH values), type stack, spacing scale, structural fingerprint, motion tokens, and the named anti-patterns the page must continue to avoid. Other AI tools (Cursor, v0, Bolt) can read this file directly to keep iterating on the same design language.
|
||||
|
||||
**Why it matters.** Closes the loop between Hallmark and the rest of the agent ecosystem. The skill stops being a one-shot generator and becomes a system that hands its decisions forward.
|
||||
@@ -134,7 +132,7 @@ A list of tempting directions that would make Hallmark worse, not better. Forcin
|
||||
- **Don't ship a UI library.** Hallmark is a *taste* skill, not a component kit. shadcn/ui and Geist exist; refer users to them. Building components inside Hallmark dilutes the focus.
|
||||
- **Don't add A/B testing or analytics** to the skill. It's not a SaaS product.
|
||||
- **Don't build a Figma plugin.** The skill works in code; that's a feature, not a limit. Designers who want Figma have other tools.
|
||||
- **Don't add prompts to "match a brand"** by URL scraping. That's SkillUI's job — point users there.
|
||||
- **Don't add prompts to "match a brand"** by URL scraping on the *default* verb. That's SkillUI's job — point users there. **Exception:** `hallmark study` accepts URLs as a source for DNA extraction (read-only; never to clone the surface). The same refusal heuristics that govern image-mode `study` apply — marketplaces, template demos, and disclosed competitors are auto-refused before WebFetch fires.
|
||||
- **Don't add image generation.** Out of scope; AI imagery is its own problem space, and the right answer is usually "use real photos" or "no image."
|
||||
|
||||
---
|
||||
|
||||
+36
-17
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: hallmark
|
||||
description: Use this skill ONLY when the user explicitly wants Hallmark's anti-AI-slop discipline applied. Triggers are narrow on purpose — (1) the user names one of Hallmark's three explicit verbs (`audit`, `redesign`, `study`, e.g. "audit this UI", "redesign this page", "study this screenshot"); (2) the user says a UI "feels AI-generated", "looks templated", "looks like every other AI page", or asks to "make it less AI-generated"; (3) the user attaches a screenshot of a design they admire and wants the DNA extracted (the `study` verb); (4) the user invokes the skill by name ("use Hallmark", "/hallmark"). DO NOT trigger on generic UI requests — "design a button", "build me a form", "make a dashboard", "build a landing page", "add a navbar". Those are handled by frontend-design or other UI skills. Hallmark is the opinionated anti-slop ruleset; it should only run when the user explicitly wants that specific discipline, not as a default UI builder.
|
||||
description: Use this skill ONLY when the user explicitly wants Hallmark's anti-AI-slop discipline applied. Triggers are narrow on purpose — (1) the user names one of Hallmark's three explicit verbs (`audit`, `redesign`, `study`, e.g. "audit this UI", "redesign this page", "study this screenshot", "study this URL"); (2) the user says a UI "feels AI-generated", "looks templated", "looks like every other AI page", or asks to "make it less AI-generated"; (3) the user attaches a screenshot OR pastes a URL of a design they admire and wants the DNA extracted (the `study` verb); (4) the user invokes the skill by name ("use Hallmark", "/hallmark"). DO NOT trigger on generic UI requests — "design a button", "build me a form", "make a dashboard", "build a landing page", "add a navbar". Those are handled by frontend-design or other UI skills. Hallmark is the opinionated anti-slop ruleset; it should only run when the user explicitly wants that specific discipline, not as a default UI builder.
|
||||
version: 1.0.0
|
||||
---
|
||||
|
||||
@@ -25,9 +25,9 @@ Hallmark has one default behaviour and three explicit verbs.
|
||||
| *(default)* | The user asked you to design or build something new. Follow the **Design flow** below. |
|
||||
| `hallmark audit <target>` | Read the target, score it against the anti-pattern list, return a ranked punch list. **Do not edit.** |
|
||||
| `hallmark redesign <target> [--mood <name>]` | Take the target's content and intent, throw out the structure, and **rebuild it from scratch with a deliberately different structural fingerprint.** New section rhythm, new heading placement, new component voice. Preserve copy, brand, and information architecture; replace everything else. |
|
||||
| `hallmark study <screenshot>` | The user pasted or attached an image of a design they admire. Extract the **DNA** — macrostructure, archetypes, type-pairing role, colour anchor — and produce a diagnosis report, then optionally rebuild the user's content using the extracted DNA. **Never copies pixels. Never claims to identify exact fonts. Refuses obvious template-marketplace or competitor-page screenshots.** Load [`references/study.md`](references/study.md) before this verb runs. |
|
||||
| `hallmark study <screenshot \| URL>` | The user pasted or attached an image of a design they admire, **or** pasted a URL to a live page. Extract the **DNA** — macrostructure, archetypes, type-pairing, colour anchor — and produce a diagnosis report, then optionally rebuild the user's content using the extracted DNA. Detection is automatic: a URL (`http://` / `https://` prefix) routes to URL mode; anything else routes to image mode. **URL mode** reads the page's HTML and CSS via WebFetch — it can name exact fonts and exact colour values, but can't judge rhythm. **Never copies pixels. Refuses template-marketplace URLs and competitor pages. Falls back to asking for a screenshot if the URL is auth-walled, a JS-only SPA shell, or otherwise un-readable.** Load [`references/study.md`](references/study.md) before this verb runs. |
|
||||
|
||||
If the user types anything that does not clearly map to `audit`, `redesign`, or `study`, treat it as default. If the user attaches an image without a verb prefix, ask: *"Should I `study` this (extract the DNA), or should I treat it as a reference for a fresh build?"*
|
||||
If the user types anything that does not clearly map to `audit`, `redesign`, or `study`, treat it as default. If the user attaches an image or pastes a URL without a verb prefix, ask: *"Should I `study` this (extract the DNA), or should I treat it as a reference for a fresh build?"*
|
||||
|
||||
The default Design flow always picks a theme. By default it picks one of the **22 named themes** — the *catalog* — and rotates among them per the diversification rule. There is also a quiet *custom* branch that constructs a one-off OKLCH palette + free-font pairing for the brief; the custom route fires **only when the brief carries a creative-intent signal** (the user names a brand colour, names a multi-attribute vibe the catalog can't carry, or explicitly asks for a custom theme). For vanilla briefs, the user never sees the words "catalog" or "custom" — the catalog runs silently. See Step 1 (signal detection) and Step 2.6 (dispatch); the protocol lives in [`references/custom-theme.md`](references/custom-theme.md).
|
||||
|
||||
@@ -514,45 +514,64 @@ Load [`references/verbs/redesign.md`](references/verbs/redesign.md) and follow i
|
||||
|
||||
## `hallmark study`
|
||||
|
||||
The user has attached or pasted a screenshot of a design they admire. They want to learn from it — its shape, its type, its rhythm — and apply that *DNA* to their own content. They do not want a pixel-faithful copy.
|
||||
The user has supplied a reference — either an attached screenshot or a URL to a live page — of a design they admire. They want to learn from it — its shape, its type, its rhythm — and apply that *DNA* to their own content. They do not want a pixel-faithful copy.
|
||||
|
||||
**Critical position:** `study` extracts structure, not pixels. It names the macrostructure, the archetypes, the type-pairing role, the colour anchor, the rhythm. It produces a *diagnosis report* before any code, then offers to rebuild the user's content using the extracted DNA. Pixel-cloning is not a feature.
|
||||
**Critical position:** `study` extracts structure, not pixels. It names the macrostructure, the archetypes, the type-pairing, the colour anchor, and (in image mode) the rhythm. It produces a *diagnosis report* before any code, then offers to rebuild the user's content using the extracted DNA. Pixel-cloning is not a feature.
|
||||
|
||||
**Always read [`references/study.md`](references/study.md) before invoking this verb.** That file contains the vision-extraction protocol, the structured-fields schema, the refusal heuristics, and the type-role vocabulary. Do not work from intuition.
|
||||
**Always read [`references/study.md`](references/study.md) before invoking this verb.** That file contains the source-mode detection rules, the extraction protocol (vision-pass for image mode, HTML/CSS-pass for URL mode), the structured-fields schema, the refusal heuristics (both image-mode and URL-mode refuse lists), the junk-or-blocked detection for URLs, and the type-role vocabulary. Do not work from intuition.
|
||||
|
||||
### Source-mode detection
|
||||
|
||||
If the user's input starts with `http://` or `https://` → **URL mode**. Otherwise → **image mode**. Same verb, same diagnosis output, different signal sources. The two modes share the schema and the diagnosis shape; they differ on what each extraction step can know — see `study.md` § Source mode.
|
||||
|
||||
### Pipeline
|
||||
|
||||
1. **Refuse-or-proceed check.** Before extracting anything, run the refusal heuristics from `study.md`. If the screenshot is clearly a paid template marketplace listing, a competitor's live marketing page, or someone's published portfolio, ask: *"Is this your own work, a public reference for inspiration, or someone else's live site?"* Educational use of public references is fine; copying a competitor's live page is not.
|
||||
1. **Refuse-or-proceed check.** Before extracting anything (and in URL mode, **before WebFetch fires**), run the refusal heuristics in `study.md`. Image mode checks the image's content; URL mode runs the URL refuse list (themeforest, framer.com/templates, webflow.com/templates, gumroad UI-kit listings, dribbble shots, behance galleries, disclosed competitors). Ambiguous sources get one short question: *"Is this your own work, a public reference for inspiration, or someone else's live site?"*
|
||||
|
||||
2. **Vision pass.** Read the image into the structured-fields schema in `study.md`. Output ten fields: macrostructure name, hero archetype + variation knobs, pitch archetype + knobs, footer archetype, display family role (never a guessed font name), body family role, surface lightness band (paper L%), accent hue band + chroma, density verdict, type-pairing role.
|
||||
2. **Extraction pass.**
|
||||
- **Image mode:** vision-pass on the attached capture per `study.md` § Five-step protocol.
|
||||
- **URL mode:** WebFetch the URL, then parse the returned HTML and any linked stylesheets. If the response trips any junk-or-blocked signal (auth wall, SPA shell, non-2xx response, no styling signal, < 1 KB body), **fall back** — emit the screenshot-fallback message from `study.md` § Junk-or-blocked detection and stop. Do not silently degrade.
|
||||
|
||||
Output the structured-fields schema in `study.md` § The structured fields. URL mode fills the mode-conditional fields (`display_face`, `body_face`, `paper_value`, `accent_value`, `motion_library`) with exact values; image mode leaves those null.
|
||||
|
||||
3. **Diagnosis report.** Return a one-page "this is what you're looking at": names the macrostructure, names the archetypes, points at the type pairing, identifies one or two anti-patterns the screenshot has that the user should *not* carry over. The diagnosis is the deliverable for users who only want to learn.
|
||||
3. **Diagnosis report.** Return a one-page "this is what you're looking at" using the matching template (image-mode template or URL-mode template) from `study.md` § The diagnosis report. Names the macrostructure, names the archetypes, points at the type pairing (with exact font names in URL mode), identifies anti-patterns the user should *not* carry over. URL-mode diagnoses must also call out the rhythm blind spot.
|
||||
|
||||
4. **Confirmation question.** Ask: *"Adopt this DNA wholesale, or change one axis? For example, I could keep the macrostructure but pick a theme that better matches your tone."* Wait for the user's answer before building.
|
||||
|
||||
5. **Build.** Pick the closest matching theme from the catalog. Stamp the comment with the inferred macrostructure + archetypes + theme. The user's content goes in; the screenshot's content does not.
|
||||
5. **Build.** Pick the closest matching theme from the catalog. Stamp the comment with the inferred macrostructure + archetypes + theme + source mode. The user's content goes in; the source's content does not.
|
||||
|
||||
### Output contract for `study`
|
||||
|
||||
When `study` produces code, the macrostructure stamp must include a `studied: yes` flag and the theme picked, e.g.:
|
||||
When `study` produces code, the macrostructure stamp must include a `studied: yes` flag, the theme picked, and the source mode. Image mode example:
|
||||
|
||||
```css
|
||||
/* Hallmark · macrostructure: Marquee Hero · H1 hero knobs: size=xxl, alignment=left-bias
|
||||
* theme: Studio · accent: forest-green ~3% · studied: yes · DNA-source: user reference
|
||||
* theme: Studio · accent: forest-green ~3% · studied: yes · DNA-source: image (user reference)
|
||||
*/
|
||||
```
|
||||
|
||||
The stamp signals to future Hallmark runs that this page's structure was extracted, not invented. That matters for the audit verb: a `studied: yes` page should be audited *more* leniently for "Specimen fall-through" (the user explicitly chose this DNA) but *more* strictly for "did you actually use the extracted DNA, or did you drift back to defaults?"
|
||||
URL mode example — additionally records the URL and any exact-fonts / exact-colours that informed the build:
|
||||
|
||||
```css
|
||||
/* Hallmark · macrostructure: Marquee Hero · H1 hero knobs: size=xxl, alignment=left-bias
|
||||
* theme: Studio · accent: forest-green ~3% · studied: yes · DNA-source: url
|
||||
* source-url: https://example.com/ · observed-fonts: Inter Tight + Inter
|
||||
* observed-accent: oklch(58% 0.16 35) · rhythm: unknown (URL mode)
|
||||
*/
|
||||
```
|
||||
|
||||
The stamp signals to future Hallmark runs that this page's structure was extracted, not invented. That matters for the audit verb: a `studied: yes` page is audited *more* leniently for "Specimen fall-through" (the user explicitly chose this DNA) but *more* strictly for "did you actually use the extracted DNA, or did you drift back to defaults?"
|
||||
|
||||
### Limits to spell out to the user
|
||||
|
||||
When you return the diagnosis, name the limits explicitly:
|
||||
|
||||
- **Fonts:** the skill names a *role* (e.g., "italic editorial serif", "heavy condensed sans", "monospace dev"), not a font ID. It proposes one or two real candidates from the canon and asks the user to confirm. Visual font identification is unreliable; do not pretend otherwise.
|
||||
- **Imagery:** the skill never copies the screenshot's photography. It generates structurally-equivalent placeholders or asks for the user's own assets.
|
||||
- **Theme drift is allowed.** If the screenshot is a Specimen and the user's content is a SaaS landing page, the skill picks a different theme. The DNA is the macrostructure + archetype + colour-anchor + type-pairing — not the dress.
|
||||
- **Fonts:** in image mode, the skill names a *role* and proposes one or two real candidates from the canon — visual font ID is unreliable. In URL mode, the skill names the *exact* fonts the page loads (via `@font-face`, Google Fonts, `next/font`). The role still drives the rebuild — Hallmark may pick a different specific face for the user's content.
|
||||
- **Imagery:** the skill never copies the source's photography. It generates structurally-equivalent placeholders or asks for the user's own assets.
|
||||
- **Theme drift is allowed.** If the source is a Specimen and the user's content is a SaaS landing page, the skill picks a different theme. The DNA is the macrostructure + archetype + colour-anchor + type-pairing — not the dress.
|
||||
- **Rhythm is the URL-mode blind spot.** HTML alone can't tell you whether the visual rhythm reads generous or templated. URL-mode diagnoses always state this and offer a screenshot fallback if it matters.
|
||||
|
||||
If `references/study.md` cannot be loaded for any reason, refuse the verb politely and direct the user to `hallmark redesign` with a written description of what they want from the screenshot.
|
||||
If `references/study.md` cannot be loaded for any reason, refuse the verb politely and direct the user to `hallmark redesign` with a written description of what they want from the source.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+146
-20
@@ -1,13 +1,59 @@
|
||||
# Study — extracting design DNA from a screenshot
|
||||
# Study — extracting design DNA from a screenshot or URL
|
||||
|
||||
This file is loaded when the `hallmark study` verb runs. It defines the protocol for reading a screenshot the user attached, naming what makes it work, and producing a *diagnosis report* the user can accept or amend before any code is built.
|
||||
This file is loaded when the `hallmark study` verb runs. It defines the protocol for reading a reference the user supplied — either a screenshot they attached or a URL to a live page — naming what makes it work, and producing a *diagnosis report* the user can accept or amend before any code is built.
|
||||
|
||||
**The promise.** `study` extracts the **DNA** of a design — its macrostructure, its component archetypes, its type-pairing role, its colour anchor, its rhythm — and lets the user apply that DNA to their own content. It does not copy pixels. It does not claim to identify exact fonts. It does not output a façade of the source.
|
||||
**The promise.** `study` extracts the **DNA** of a design — its macrostructure, its component archetypes, its type-pairing, its colour anchor, its rhythm — and lets the user apply that DNA to their own content. It does not copy pixels. It does not output a façade of the source.
|
||||
|
||||
**The mental model.** A designer who likes a reference site does not photocopy it. They look at it long enough to say "ah — that's a Marquee Hero with a single column body, italic-editorial display paired with monospace labels, anchored on a desaturated forest green at maybe 3 % footprint, with hairline rules and one orchestrated entrance." Then they go build something *different* with the same skeleton. That sentence is what `study` outputs. The build is what `default` or `redesign` does after.
|
||||
|
||||
---
|
||||
|
||||
## Source mode — image or URL
|
||||
|
||||
`study` accepts **either** an image (a screenshot the user attached) **or** a URL to a live page. Same verb, same diagnosis output, different signal sources. Detection is automatic: if the user's input starts with `http://` or `https://` → URL mode; anything else (an attached image, a pasted capture) → image mode.
|
||||
|
||||
The two modes share the schema, the refusal heuristics, and the diagnosis-report shape. They differ on what each step of the protocol can know:
|
||||
|
||||
| Step | Image mode | URL mode |
|
||||
| --- | --- | --- |
|
||||
| 1 Surface | colour bands and footprint, estimated by eye | exact OKLCH / hex / rgb values pulled from CSS custom properties and `:root` declarations |
|
||||
| 2 Type | *roles only* — "italic editorial serif" | roles **plus exact font names** when the page declares them via `@font-face`, Google Fonts `<link>`, `next/font`, or hard-coded `font-family` |
|
||||
| 3 Structure | inferred from visible regions | inferred from real DOM (`<nav>`, `<section>`, `<main>`, `<footer>`, semantic tags) |
|
||||
| 4 Motion | usually "not visible — assuming default reveals" | observable — read from `<script src>` tags (framer-motion, gsap, lottie-web, lenis, motion) and CSS `@keyframes` / `transition` declarations |
|
||||
| 5 Rhythm | observable directly from the visual gestalt | **not observable** — HTML alone can't tell you density / asymmetry / pacing. Mark this as a known blind spot in the diagnosis. |
|
||||
|
||||
URL mode trades the rhythm pass for everything else getting more accurate. If rhythm is what the user wants extracted, they should attach a screenshot instead — or alongside the URL, but Hallmark still defaults to one source at a time (see the "One screenshot, one diagnosis" rule in § Limits).
|
||||
|
||||
### URL mode — fetch pipeline
|
||||
|
||||
When the input is a URL:
|
||||
|
||||
1. **URL refusal check.** Run the URL refuse list in § Refusal **before fetching anything**. Auto-refuse on a domain match. Marketplaces and template demos don't get a WebFetch call at all.
|
||||
2. **Fetch.** Use the WebFetch tool on the URL. Ask for the rendered HTML plus any linked stylesheets referenced via `<link rel="stylesheet">`. If WebFetch can only return one consolidated response, ask for "the full HTML source plus the contents of any `<style>` blocks and `:root` token declarations."
|
||||
3. **Junk-or-blocked check.** Decide if the fetch was useful using the heuristics in § Junk-or-blocked detection below. If the page is auth-walled, an empty SPA shell, or otherwise un-readable, fall back to asking the user for a screenshot. Do not silently degrade.
|
||||
4. **Extract.** Run the five-step protocol against the HTML / CSS payload. Every step except Rhythm produces concrete values; Rhythm is marked `unknown (URL mode)` in the schema and called out as a blind spot in the diagnosis.
|
||||
5. **Schema + diagnosis.** Fill the schema (URL-mode fields noted inline in § The structured fields). Emit the diagnosis using the URL-mode template variant in § The diagnosis report.
|
||||
|
||||
### Junk-or-blocked detection
|
||||
|
||||
After WebFetch returns, decide if the payload is usable. Any one of these signals triggers the screenshot fallback:
|
||||
|
||||
| Signal | What it means |
|
||||
| --- | --- |
|
||||
| HTML contains `<input type="password">` or `<form action="/login">` *and* total visible text < 500 chars | Auth wall — the page didn't render past the login |
|
||||
| `<body>` text content < 200 chars *and* the page has a `<div id="root">`, `<div id="__next">`, `<div id="app">`, or similar SPA mount node | Client-rendered SPA — WebFetch only saw the JS shell |
|
||||
| HTTP status was non-2xx, or WebFetch returned an error | The URL didn't resolve / blocked the request |
|
||||
| No `<link rel="stylesheet">`, no `<style>` blocks, no inline `style=` attributes | The page has no usable styling signal — typically a robots-blocked or CDN-blocked response |
|
||||
| The fetched HTML is < 1 KB total | The origin returned a minimal stub, not the real page |
|
||||
|
||||
**Fallback message** (use this verbatim, swap the bracketed reason):
|
||||
|
||||
> *I tried to read this URL but [the page is behind a login / it's a client-rendered SPA and only the JS shell came back / the URL didn't respond / there's no styling signal in the response]. Could you paste a screenshot instead? `study` works equally well from images — URL mode just needs the page to render server-side.*
|
||||
|
||||
A half-blind diagnosis is worse than asking once. If type, colour, AND structure can't all be extracted, fall back.
|
||||
|
||||
---
|
||||
|
||||
## Refusal — when not to study
|
||||
|
||||
Run this check **before** extracting anything. If any of the following is true, refuse politely and offer an alternative.
|
||||
@@ -24,25 +70,44 @@ Run this check **before** extracting anything. If any of the following is true,
|
||||
|
||||
**Never** silently proceed when you suspect the screenshot is a marketplace listing or a competitor. The user must explicitly confirm. The cost of asking is low; the cost of building a knockoff is reputational.
|
||||
|
||||
### URL refuse list (auto-refuse on domain match)
|
||||
|
||||
In URL mode, run this **before** WebFetch fires — don't even fetch the page. If the URL matches any pattern, refuse and offer the redirect.
|
||||
|
||||
| If the URL host / path is… | Then… |
|
||||
| --- | --- |
|
||||
| `themeforest.net/*`, `templatemonster.com/*`, `themely.com/*` (paid template marketplaces) | Refuse. *"This looks like a template marketplace listing. I won't study it. Tell me what about it you like and I'll build with `hallmark default` instead."* |
|
||||
| `framer.com/templates/*`, `*.framer.website` (Framer marketplace + template demos), `webflow.com/templates/*` (Webflow templates) | Refuse same as above — these are the marketplace ecosystem by another name. |
|
||||
| `gumroad.com/*` where the page is selling a UI kit or template (heuristic: `og:type=product` plus *template*, *UI kit*, *starter*, *bundle* in the title) | Refuse. |
|
||||
| `dribbble.com/shots/*`, `behance.net/gallery/*` (designer presentation work) | Soft-refuse. *"These are individual designers' presentation pieces — I'll extract DNA only, not reproduce signature choices. If a specific designer's voice resonates, tell me what about it does."* |
|
||||
| Any URL the user discloses as a direct competitor | Refuse the build. *"I'll extract the structural pattern but won't reproduce a competitor's surface. Would the pattern alone be useful?"* |
|
||||
| Anything ambiguous (an unfamiliar agency page, a personal portfolio, an unknown SaaS) | **Ask once:** *"Is this your own site, a public reference you admire, or a competitor? If competitor or marketplace, I'll skip the build and give you the diagnosis only."* |
|
||||
|
||||
The image-mode refusal rules above still apply by analogy in URL mode — if the page reads as signature work from a known designer, soft-refuse the same way.
|
||||
|
||||
---
|
||||
|
||||
## The five-step protocol
|
||||
|
||||
Read the screenshot in this order. Each step builds on the previous; do not skip ahead.
|
||||
Read the source in this order. Each step builds on the previous; do not skip ahead. In image mode, "read" means a vision pass on the attached capture. In URL mode, "read" means parsing the WebFetch'd HTML plus any inlined or linked CSS. Where the two modes differ, the step calls it out explicitly.
|
||||
|
||||
### Step 1 — Surface
|
||||
|
||||
Before reading any text, look at the page's *colour temperament*.
|
||||
|
||||
- **Paper lightness band.** Is the background dark (L < 30 %), light (L > 85 %), or mid (between)? You don't need an exact value — pick a band.
|
||||
- **Paper lightness band.** Is the background dark (L < 30 %), light (L > 85 %), or mid (between)?
|
||||
- **Paper hue.** Does the background tilt warm (yellow/orange/red, hue 30–90), cool (blue/indigo, 220–290), neutral-warm (slight 60–80), neutral-cool (slight 240–270), or chromatic (clearly purple/green/etc.)?
|
||||
- **Anchor accent hue.** What single colour appears as accent — links, marks, buttons, small flourishes? Estimate the hue band: warm-red (10–30), orange (40–60), yellow (80–110), green (130–160), teal (180–210), cyan-blue (210–240), indigo (260–290), magenta (300–340), neutral (no chromatic accent — just ink-on-paper).
|
||||
- **Accent footprint.** Is the accent a small mark (≤ 5 % of viewport), a recurring underline (5–15 %), or a flood (large blocks, > 15 %)? This dictates how loud the page is.
|
||||
- **Distinctive treatments.** Off-register text-shadow (riso), grain overlay, glassmorphism, dark-mode-with-lightness-elevation, paper texture? Note them.
|
||||
|
||||
**URL mode override.** Pull paper and accent values directly from the fetched CSS. Look for `:root` blocks, `--color-*` / `--bg-*` / `--accent-*` / `--brand-*` custom properties, and the `background-color` / `color` declared on `body`, `main`, and primary buttons / links. Record both the band (for the schema's `paper_band` / `accent_hue_band` fields) **and** the exact value (record it in the schema's `paper_value` / `accent_value` fields — these only exist in URL mode). If the page uses Tailwind, look at the `bg-*` / `text-*` utility classes on `<body>` and primary actions and map them back to the theme.
|
||||
|
||||
### Step 2 — Type
|
||||
|
||||
Read the type *roles*, not the typeface names. You will be wrong if you guess a typeface from a screenshot — even your best guess is unreliable. Name what each face is *doing*.
|
||||
Read the type *roles*. In image mode, you do not name typefaces — you'll be wrong about half the time. In URL mode, you **do** name typefaces — the page tells you.
|
||||
|
||||
Pick the role each face is playing:
|
||||
|
||||
- **Display role.** What is carrying the headline? Pick from: *italic editorial serif · roman editorial serif · heavy condensed sans · soft geometric sans · expressive variable sans · monospace · pixel · ornamental script*.
|
||||
- **Body role.** What is carrying the prose? *roman serif · italic serif · neutral grotesque · soft geometric sans · monospace*.
|
||||
@@ -50,13 +115,22 @@ Read the type *roles*, not the typeface names. You will be wrong if you guess a
|
||||
- **Pairing logic.** Same family with weight/italic split, or two different families? If two, what's the contrast — *editorial serif + grotesque body, mono labels* (the modern editorial agency look), or *condensed display + body sans + mono labels* (technical), etc.?
|
||||
- **Display weight.** Light (≤ 300), regular (400–500), heavy (700+), extra-bold (800+).
|
||||
|
||||
Do not write "this is Söhne" or "this is Inter". Write "this is a neutral grotesque body".
|
||||
**Image mode rule.** Do not write "this is Söhne" or "this is Inter". Write "this is a neutral grotesque body" and propose 1–2 candidates from the canon in the diagnosis.
|
||||
|
||||
**URL mode override.** Read the actual font declarations. The sources, in order of reliability:
|
||||
|
||||
1. `<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=…">` — names the Google Fonts loaded. Authoritative.
|
||||
2. `@font-face { font-family: "…"; src: url(…) }` in CSS — names self-hosted faces. Authoritative.
|
||||
3. `next/font` imports in the HTML's preloaded fonts (`<link rel="preload" as="font" href="/_next/static/media/…woff2">` with a `data-font-family` hint, or referenced in inlined `<style>`). Reliable.
|
||||
4. Hard-coded `font-family: "Geist", system-ui, sans-serif` declarations on `body`, `h1`, etc. Authoritative for what's *intended*, even if the font isn't actually loaded.
|
||||
|
||||
When URL mode names a face, still record the role (the role is what travels into the rebuilt page), and record the name as a side fact. The schema gets both: `display_role: "neutral grotesque"` AND `display_face: "Inter"`. The diagnosis report can then say *"the page loads Inter Tight for display and Inter for body — both neutral grotesques."*
|
||||
|
||||
### Step 3 — Structure
|
||||
|
||||
Match the page to one of the twenty-one named macrostructures in [`macrostructures.md`](macrostructures.md). Pick the *closest*; if it's between two, name both and say which it leans toward.
|
||||
|
||||
For each section visible in the screenshot, also pick an archetype from [`component-cookbook.md`](component-cookbook.md):
|
||||
For each section visible in the source, also pick an archetype from [`component-cookbook.md`](component-cookbook.md):
|
||||
|
||||
- **Hero** → H1–H6 (or F6 for product-led pages).
|
||||
- **Pitch / first content block** → F1–F5 (or F6 for catalogue).
|
||||
@@ -65,11 +139,21 @@ For each section visible in the screenshot, also pick an archetype from [`compon
|
||||
|
||||
For each archetype, also pick **variation knobs** from the cookbook's variation-knob table. *"H2 Split Diptych · ratio=7/5 · right-side=proof column · divider=hairline."* The knobs are what distinguishes one Bento from another; capturing them is what makes the diagnosis useful.
|
||||
|
||||
**URL mode override.** Read the DOM directly. Count `<section>` / `<article>` / `<main>` blocks. Inspect the first one for hero-archetype tells (is there a single `<h1>` + `<p>` + `<a class="…btn…">` → H1 Marquee; is there a `grid-cols-2` wrapper around the hero → H2 Split; is there an `<img>` with `object-cover` filling the hero → H6 Photographic). Inspect the `<nav>` for its archetype (count links; check for a logo + 4–5 inline links + button-right → N1 Standard; floating `position: fixed` with rounded-full → N5 Floating pill). Inspect the `<footer>` for its archetype (4 column grid + social row → Ft3 Index; one big statement line → Ft5; minimal copyright row → Ft1). The DOM is concrete — use it.
|
||||
|
||||
### Step 4 — Motion
|
||||
|
||||
If the screenshot is static, skip this section but note: *"motion not visible in static capture — assuming default reveals."*
|
||||
**Image mode.** If the screenshot is static, skip this section but note: *"motion not visible in static capture — assuming default reveals."* If the screenshot is animated (a GIF, a recorded screen, or the user describes the motion in text), record the reveal / easing / microinteraction tells described below.
|
||||
|
||||
If the screenshot is animated (a GIF, a recorded screen, or the user describes the motion in text):
|
||||
**URL mode override.** Motion is observable from the page's scripts and CSS. Read these signals:
|
||||
|
||||
- `<script src="…framer-motion…">`, `<script src="…gsap…">`, `<script src="…lottie-web…">`, `<script src="…lenis…">`, `<script src="…motion@…">` → record the motion library in use.
|
||||
- CSS `@keyframes` blocks → name them (e.g. `fade-up`, `marquee`, `reveal`), and note which selectors apply them.
|
||||
- CSS `transition: all …` declarations → flag as the *transition-all* anti-pattern.
|
||||
- CSS `transform: scale(1.05)` on `:hover` → flag as the hover-scale anti-pattern.
|
||||
- `<script>` blocks referencing `IntersectionObserver` with class toggles → record as scroll-triggered reveal.
|
||||
|
||||
Then categorise:
|
||||
|
||||
- **Reveal pattern.** None · fade-up stagger · horizontal sweep · type-unmask · number-tick · typewriter.
|
||||
- **Easing voice.** Conservative (ease-out exponential) · physical (slight overshoot, drag-release) · none.
|
||||
@@ -84,6 +168,8 @@ The hardest one. Look at the *density and pacing*:
|
||||
- **Negative space discipline.** Generous (luxury / atelier / specimen) · medium (modern editorial) · dense (newsprint / catalogue / index)?
|
||||
- **Asymmetry.** Centred symmetric (formal, Apple-product-page energy) · left-biased (editorial) · right-biased (rare, atelier-like) · asymmetric grid spans (specimen, bento)?
|
||||
|
||||
**URL mode override.** Rhythm is the one step URL mode can't carry. HTML can tell you a section has `padding: 8rem 0` but not whether the *visual rhythm* of that 8rem reads generous or templated next to its neighbours — that's a gestalt judgement. Record what the CSS literally declares (padding values, gap values, grid-template-columns ratios) as raw facts, mark the four rhythm axes above as `unknown (URL mode)` in the schema, and call this out as a blind spot in the diagnosis: *"I read this from the page's HTML, not a screenshot — I can name the macrostructure, the type, the colour, and the motion, but I can't tell you whether the rhythm reads generous or templated. If that matters, send a screenshot too."*
|
||||
|
||||
---
|
||||
|
||||
## The structured fields
|
||||
@@ -92,6 +178,8 @@ After the five-step pass, fill out this schema. The diagnosis report is built fr
|
||||
|
||||
```
|
||||
{
|
||||
"source_mode": "image | url",
|
||||
"source_url": "<the URL if source_mode=url, else null>",
|
||||
"source": "user-described | public-reference | unknown",
|
||||
"refusal": "ok | refused (paid-template) | refused (competitor) | soft-refusal (signature work)",
|
||||
"macrostructure": "<name from macrostructures.md>",
|
||||
@@ -101,24 +189,31 @@ After the five-step pass, fill out this schema. The diagnosis report is built fr
|
||||
"knobs": { "<knob A>": "<value>", "<knob B>": "<value>" }
|
||||
},
|
||||
"pitch": { "archetype": "...", "knobs": { ... } },
|
||||
"footer": { "archetype": "...", "knobs": { ... } },
|
||||
"nav": { "archetype": "N1 | N2 | … | N9", "knobs": { ... } },
|
||||
"footer": { "archetype": "Ft1 | Ft2 | … | Ft8", "knobs": { ... } },
|
||||
"display_role": "italic editorial serif | heavy condensed sans | ...",
|
||||
"display_face": "<exact font name in URL mode, else null>",
|
||||
"body_role": "neutral grotesque | italic serif | ...",
|
||||
"body_face": "<exact font name in URL mode, else null>",
|
||||
"label_role": "monospace | small-caps serif | uppercase grotesque | none",
|
||||
"label_face": "<exact font name in URL mode, else null>",
|
||||
"pairing_logic": "single family / two families / three families",
|
||||
"paper_band": "dark <30 | mid 30-85 | light >85",
|
||||
"paper_value": "<exact oklch/hex/rgb in URL mode, else null>",
|
||||
"paper_hue": "warm | cool | neutral-warm | neutral-cool | chromatic-<hue>",
|
||||
"accent_hue_band": "warm-red | orange | yellow | green | teal | cyan-blue | indigo | magenta | neutral",
|
||||
"accent_value": "<exact oklch/hex/rgb in URL mode, else null>",
|
||||
"accent_footprint": "small ≤5% | recurring 5-15% | flood >15%",
|
||||
"density": "generous | medium | dense",
|
||||
"asymmetry": "centred | left-biased | right-biased | asymmetric-grid",
|
||||
"density": "generous | medium | dense | unknown (URL mode)",
|
||||
"asymmetry": "centred | left-biased | right-biased | asymmetric-grid | unknown (URL mode)",
|
||||
"treatments": ["riso", "grain-overlay", "glassmorphism", "dark-elevation-lightness", "..."],
|
||||
"reveal": "none | fade-up | sweep | type-unmask | number-tick | typewriter | (not-visible)",
|
||||
"motion_library": "<framer-motion | gsap | lottie | lenis | motion | none — only set in URL mode>",
|
||||
"anti_patterns": ["bouncy hover", "transition-all", "..."]
|
||||
}
|
||||
```
|
||||
|
||||
Every field is required (no nulls; if a field is genuinely unknowable from the image, write `"unknown"`). The schema is the contract; the diagnosis report is the human-readable rendering of it.
|
||||
Every field is required (no nulls except where the schema explicitly notes a mode-conditional field; if a field is genuinely unknowable, write `"unknown"`). The `*_face`, `*_value`, and `motion_library` fields are mode-conditional — they carry exact values in URL mode and `null` in image mode. `density` and `asymmetry` carry `unknown (URL mode)` when source_mode is `url`. The schema is the contract; the diagnosis report is the human-readable rendering of it.
|
||||
|
||||
---
|
||||
|
||||
@@ -151,6 +246,8 @@ If two themes are equally close, pick whichever is more *categorically distant*
|
||||
|
||||
After the schema and the theme map, produce a one-page report in this shape. Keep it short — about ten sentences. The user reads this *before* approving any code.
|
||||
|
||||
### Image-mode template
|
||||
|
||||
```
|
||||
You sent me a [macrostructure name].
|
||||
|
||||
@@ -176,7 +273,35 @@ That's a candidate, not a requirement — your content might point elsewhere.
|
||||
Want me to build with this DNA, or change one axis first?
|
||||
```
|
||||
|
||||
The last line is the **confirmation question**. Wait for the user before building.
|
||||
### URL-mode template
|
||||
|
||||
```
|
||||
I read [URL].
|
||||
|
||||
The page is a [macrostructure name]. The hero is an [archetype name] with
|
||||
[knob values]. Nav is [N-archetype]; footer is [Ft-archetype].
|
||||
|
||||
The page loads [display_face] for display and [body_face] for body[, with
|
||||
<label_face> for labels]. Roles: [display role] + [body role][ + <label role>].
|
||||
|
||||
The paper is [exact value, e.g. oklch(96% 0.01 90)] — a [paper band, hue].
|
||||
The accent is [exact value, e.g. #c0392b] — a [hue band] used at
|
||||
[footprint estimated from how many places it appears in the CSS].
|
||||
|
||||
Motion: the page uses [motion_library or "no motion library"]; reveal pattern
|
||||
is [reveal]. Anti-patterns I noticed in the CSS / scripts: [list, e.g.
|
||||
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.
|
||||
|
||||
Want me to build with this DNA, or change one axis first?
|
||||
```
|
||||
|
||||
The last line is the **confirmation question** in either mode. Wait for the user before building.
|
||||
|
||||
---
|
||||
|
||||
@@ -252,11 +377,12 @@ The last line is the **confirmation question**. Wait for the user before buildin
|
||||
|
||||
State these to the user when returning the diagnosis. Do not bury them.
|
||||
|
||||
1. **Fonts cannot be identified from screenshots reliably.** Even with What The Font, FontInDetail, or vision-LM guesses, the output is wrong roughly half the time on custom or modified faces. Hallmark names *roles* and proposes 1–2 candidates from its canon. The user owns the final call.
|
||||
2. **Imagery is never copied.** The skill's build replaces the screenshot's photography with structurally-equivalent placeholders. If the user wants real assets, they provide them.
|
||||
3. **Theme drift is allowed.** The user's content might point to a different theme than the screenshot's surface implies. The DNA is the macrostructure + archetype tuple + colour-anchor band + type-pairing role. The dress (specific typeface, specific accent hex) can change.
|
||||
4. **One screenshot, one diagnosis.** Do not let the user paste five screenshots and ask for a "blend". Pick one as the primary reference; the others can inform individual axis choices but the DNA backbone comes from one source. Five blended references is how you produce template-soup.
|
||||
5. **No surprise edits.** The diagnosis is for the user to accept. Do not write code in the same turn as the diagnosis. Wait for confirmation.
|
||||
1. **Fonts cannot be identified from screenshots reliably.** In image mode, Hallmark names *roles* and proposes 1–2 candidates from its canon — visual font ID is wrong half the time on custom or modified faces. In **URL mode** the rule flips: the page's `@font-face`, Google Fonts `<link>`, and `next/font` declarations name the typefaces authoritatively, and the diagnosis can name them. The role still travels into the rebuilt page (Hallmark may pick a different specific face from the canon for the user's content); the original name is recorded as a side fact.
|
||||
2. **Imagery is never copied.** The skill's build replaces the source's photography with structurally-equivalent placeholders. If the user wants real assets, they provide them.
|
||||
3. **Theme drift is allowed.** The user's content might point to a different theme than the source's surface implies. The DNA is the macrostructure + archetype tuple + colour-anchor band + type-pairing role. The dress (specific typeface, specific accent hex) can change — even when URL mode named the exact dress.
|
||||
4. **One source, one diagnosis.** Do not let the user paste five screenshots OR five URLs and ask for a "blend". Pick one as the primary reference; the others can inform individual axis choices but the DNA backbone comes from one source. Five blended references is how you produce template-soup.
|
||||
5. **URL mode has a known rhythm blind spot.** HTML alone can't tell you whether the visual rhythm reads generous or templated. Always call this out in URL-mode diagnoses, and offer the user the option to send a screenshot alongside if rhythm matters.
|
||||
6. **No surprise edits.** The diagnosis is for the user to accept. Do not write code in the same turn as the diagnosis. Wait for confirmation.
|
||||
|
||||
If any limit is being violated, say so plainly in the diagnosis report — *"I can't reliably identify this typeface; here are two candidates I'm guessing at"* — and let the user redirect.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user