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 @@ - - + +
+
+ +

+ 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 `