mirror of
https://github.com/Nutlope/hallmark.git
synced 2026-08-14 12:35:33 +02:00
v1.0 — anti-slop hardening, Section 03 skills showcase, drop FAQ
Section 03 ships as the five-skills showcase (Build · Study · Audit · Refine · Redesign), each row with its own structurally-distinct demo. SKILL.md and references — new disciplines that hold across every verb: · Pre-emit self-critique on six axes (Philosophy · Hierarchy · Execution · Specificity · Restraint · Variety) — anything <3 triggers revision · Honest copy — no fabricated metrics, real numbers or labelled placeholder, never invent "+47% conversion" · Locked tokens — no mid-render colour or font-family improvisation · Re-drawn UI chrome forbidden — never hand-build fake browser bars, phone frames, code-block windows, IDE chrome · Clickable text never wraps to two lines on shrink Slop test grows from 55 to 60 gates (gates 56–60). Pre-emit critique block sits above the gate sweep. anti-patterns.md gains five new named entries; responsive.md gains "Clickable text — never wraps" with the 4-step fix order. Site: · Studio photographic hero — empty 3x3 placeholder grid replaced with a 3x2 showcase of six real Hallmark output thumbnails (Static Hour, NAJM, Tally hero, Nexus, Tracejam, Tally process) · Studio — strip "· selected work" suffix from section labels (::after rule removed) and from hero eyebrow COPY · FAQ section dropped from landing page · CSS removed · Install renumbered 07 → 06, footer reveal index 7 → 6 · Section 03 Row I (Build) demo swaps Tide → Static Hour · README — concise intro paragraph, hero showcase swapped to four new outputs (Static Hour, NAJM, Tally hero, Nexus) Version bumped to 1.0.0 across package.json, SKILL.md, banner, footer, JS captions, and the artifact stamp string. 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
78167667a2
commit
22b3697bef
@@ -1,25 +1,25 @@
|
||||
# Hallmark
|
||||
|
||||
**A design skill that studies what you admire — and rebuilds your content with it.**
|
||||
**A design skill for Claude Code, Cursor, and Codex that refuses to look AI-generated.**
|
||||
|
||||
→ Live demo: **[hallmark-murex.vercel.app](https://hallmark-murex.vercel.app)** · twenty-three themes, eight worked tests, press `T` to cycle.
|
||||
→ Current version: **v0.9.0** — adds the **Editorial** theme (open-design-inspired premium · warm cream + coral + Inter Tight × Playfair italic) and a small kit of open-design utilities any theme can reach for: Roman-numeral section heads, corner-bracket image annotations, dark-slab section reversal, pulse animation for live indicators, and a `.tnum` tabular-numerals utility.
|
||||
→ Previously in **v0.8**: genres (editorial · modern-minimal · atmospheric · playful), `design.md` for whole-project redesigns, the 2+1 font rule with 55-gate slop test, component-library exports, 9 nav archetypes (incl Floating pill), 8 footer archetypes, 4 hero polish patterns, contrast gates 46–50, nav/footer/hero structural gates 51–55.
|
||||
[Live demo →](https://hallmark-murex.vercel.app) · twenty-three themes · five verbs · press `T` to cycle.
|
||||
|
||||
Powered by Together AI.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><img src="docs/img/theme-specimen.png" alt="Specimen — warm cream, italic Fraunces, warm-orange accent" /></td>
|
||||
<td><img src="docs/img/theme-studio.png" alt="Studio — cool grey paper, italic Fraunces, forest-green accent" /></td>
|
||||
<td><img src="site/_tests/_thumbs/hero-static-hour.jpg" alt="Static Hour — atmospheric podcast platform on dark canvas, italic editorial serif" /></td>
|
||||
<td><img src="site/_tests/_thumbs/hero-najm.jpg" alt="NAJM — Moroccan fashion brand, oversized condensed sans with bright accent" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="docs/img/theme-brutal.png" alt="Brutal — stark white-and-black, Inter Tight 900, no chromatic accent" /></td>
|
||||
<td><img src="docs/img/theme-newsprint.png" alt="Newsprint — warm cream, Playfair Display roman, deep-red accent" /></td>
|
||||
<td><img src="site/_tests/_thumbs/hero-tally-hero.jpg" alt="Tally — modern-minimal billing platform, live invoice card and chart" /></td>
|
||||
<td><img src="site/_tests/_thumbs/hero-nexus.jpg" alt="Nexus — developer tool, split hero with italic-emphasis sans" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Hallmark is the **anti-AI-slop** rule-set for Claude Code, Cursor, and Codex. It encodes the [tactile-rebellion](https://www.creativebloq.com/design/graphic-design/texture-warmth-and-tactile-rebellion-the-big-graphic-design-trends-for-2026) consensus — typography, colour, layout, motion, microinteractions, structural variety — into one opinionated skill that refuses to emit the on-distribution defaults every LLM was trained into.
|
||||
Hallmark encodes the anti-AI-slop consensus — typography, colour, layout, motion, microinteractions, structural variety — into one opinionated rule-set. It picks a macrostructure for the brief, dresses it in one of twenty-three themes, runs sixty slop-test gates plus a pre-emit self-critique before handing back, and refuses the on-distribution defaults every LLM was trained into.
|
||||
|
||||
Powered by Together AI.
|
||||
> **v1.0.0** — pre-emit critique on six axes, honest-copy enforcement, locked-token discipline, re-drawn-chrome ban, and a no-wrap rule for clickable text. Five new slop-test gates (56–60). The full rule-set lives in [`skill/SKILL.md`](skill/SKILL.md) and [`skill/references/`](skill/references/).
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hallmark",
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0",
|
||||
"description": "A design skill for AI coding assistants. Makes the UIs they generate look made, not generated. Powered by Together AI.",
|
||||
"keywords": [
|
||||
"claude",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
+11
-18
@@ -2000,16 +2000,6 @@
|
||||
hero crops more aggressively (16/7 ratio); pull-quote treatment leans
|
||||
editorial-magazine instead of agency-deck. */
|
||||
|
||||
[data-theme="studio"] .section-label::after {
|
||||
content: " · selected work";
|
||||
color: var(--color-muted);
|
||||
font-style: italic;
|
||||
text-transform: lowercase;
|
||||
letter-spacing: 0;
|
||||
margin-inline-start: 0.4em;
|
||||
font-feature-settings: "ss01";
|
||||
}
|
||||
|
||||
[data-theme="studio"] .hero__photo {
|
||||
aspect-ratio: 16 / 7;
|
||||
border-radius: 0;
|
||||
@@ -2512,21 +2502,24 @@
|
||||
inset: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(3, 1fr);
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
gap: 1px;
|
||||
background: var(--color-rule);
|
||||
}
|
||||
|
||||
.hero__photo-grid > span {
|
||||
background: linear-gradient(135deg,
|
||||
color-mix(in oklch, var(--color-paper-3) 80%, var(--color-accent) 5%),
|
||||
color-mix(in oklch, var(--color-neutral) 30%, var(--color-paper) 70%));
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: var(--color-paper-2);
|
||||
}
|
||||
|
||||
.hero__photo-grid > span:nth-child(2n) { background: linear-gradient(180deg, var(--color-paper-3), var(--color-paper-2)); }
|
||||
.hero__photo-grid > span:nth-child(3n) { background: linear-gradient(45deg, var(--color-paper-2), var(--color-paper-3)); }
|
||||
.hero__photo-grid > span:nth-child(5n) { background: linear-gradient(90deg, var(--color-paper-3), color-mix(in oklch, var(--color-accent) 10%, var(--color-paper))); }
|
||||
.hero__photo-grid > span:nth-child(7n) { background: var(--color-neutral); }
|
||||
.hero__photo-grid > span > img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top center;
|
||||
}
|
||||
|
||||
.hero__photo-caption {
|
||||
position: absolute;
|
||||
|
||||
+315
-106
@@ -514,136 +514,345 @@
|
||||
.study-grid { grid-template-columns: 1fr; gap: var(--space-2xl); }
|
||||
}
|
||||
|
||||
/* — 06 · FAQ — typographic Q/A ——————————————————————————
|
||||
Five numbered Q/A pairs in editorial format. Q in display face,
|
||||
A in body serif. Tighter than a typical FAQ — meant to scan, not
|
||||
loom. Re-typesets per-theme. */
|
||||
.faq {
|
||||
display: grid;
|
||||
gap: 0;
|
||||
/* — 03 · Skills — five things Hallmark does ——————————————————
|
||||
Vertical editorial list, scroll-only. No tabs, no carousel, no JS
|
||||
state. Each row: roman numeral marginalia → title + lede → demo +
|
||||
structured list. Each demo is structurally different from the others
|
||||
on purpose — the section practises what the skill preaches. */
|
||||
|
||||
.skills__intro {
|
||||
margin: 0 0 var(--space-2xl);
|
||||
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: 60ch;
|
||||
}
|
||||
|
||||
[data-theme="brutal"] .skills__intro,
|
||||
[data-theme="manifesto"] .skills__intro,
|
||||
[data-theme="terminal"] .skills__intro,
|
||||
[data-theme="sport"] .skills__intro,
|
||||
[data-theme="almanac"] .skills__intro,
|
||||
[data-theme="quiet"] .skills__intro,
|
||||
[data-theme="bloom"] .skills__intro,
|
||||
[data-theme="riso"] .skills__intro {
|
||||
font-family: var(--font-body);
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.skills-list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.faq__row {
|
||||
display: grid;
|
||||
grid-template-columns: 5rem 1fr;
|
||||
gap: 0.4rem var(--space-xl);
|
||||
align-items: baseline;
|
||||
padding-block: var(--space-lg) var(--space-md);
|
||||
padding-inline: 0;
|
||||
border-block-start: var(--rule-hair) solid var(--color-rule);
|
||||
gap: var(--space-3xl);
|
||||
}
|
||||
|
||||
.faq__row:first-child { border-block-start: 0; padding-block-start: 0; }
|
||||
.skill-row {
|
||||
display: grid;
|
||||
gap: var(--space-lg);
|
||||
}
|
||||
|
||||
@media (max-width: 50rem) {
|
||||
.faq__row {
|
||||
.skill-row__head {
|
||||
display: grid;
|
||||
grid-template-columns: 4rem 1fr;
|
||||
gap: var(--space-md);
|
||||
align-items: start;
|
||||
margin-block-end: var(--space-md);
|
||||
}
|
||||
|
||||
@media (max-width: 60rem) {
|
||||
.skill-row__head {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.4rem;
|
||||
padding-block: var(--space-md);
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.faq__q-mark {
|
||||
.skill-row__num {
|
||||
font-family: var(--font-serif);
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
font-size: var(--text-2xl);
|
||||
color: var(--color-rule-2);
|
||||
letter-spacing: 0;
|
||||
user-select: none;
|
||||
padding-block-start: 0.15em;
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
|
||||
@media (max-width: 60rem) {
|
||||
.skill-row__num { display: none; }
|
||||
}
|
||||
|
||||
[data-theme="brutal"] .skill-row__num,
|
||||
[data-theme="manifesto"] .skill-row__num,
|
||||
[data-theme="terminal"] .skill-row__num,
|
||||
[data-theme="sport"] .skill-row__num,
|
||||
[data-theme="almanac"] .skill-row__num,
|
||||
[data-theme="quiet"] .skill-row__num,
|
||||
[data-theme="bloom"] .skill-row__num,
|
||||
[data-theme="riso"] .skill-row__num {
|
||||
font-family: var(--font-mono);
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: var(--text-xl);
|
||||
}
|
||||
|
||||
.skill-row__head-body {
|
||||
display: grid;
|
||||
gap: var(--space-sm);
|
||||
max-width: 64ch;
|
||||
}
|
||||
|
||||
.skill-row__title {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(2rem, 3.4vw + 0.5rem, 3rem);
|
||||
font-weight: 500;
|
||||
line-height: var(--lh-tight);
|
||||
letter-spacing: var(--tracking-display);
|
||||
color: var(--color-ink);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
[data-theme="manifesto"] .skill-row__title,
|
||||
[data-theme="brutal"] .skill-row__title {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: var(--tracking-tight);
|
||||
}
|
||||
|
||||
.skill-row__lede {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--text-md);
|
||||
line-height: var(--lh-relaxed);
|
||||
color: var(--color-ink-2);
|
||||
margin: 0;
|
||||
max-width: 60ch;
|
||||
}
|
||||
|
||||
.skill-row__lede strong {
|
||||
font-weight: 600;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.skill-row__body {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
|
||||
gap: var(--space-xl);
|
||||
align-items: start;
|
||||
padding-inline-start: 4rem;
|
||||
}
|
||||
|
||||
@media (max-width: 60rem) {
|
||||
.skill-row__body {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-lg);
|
||||
padding-inline-start: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.skill-row__body--study {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.skill-row__demo {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.skill-row__demo img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background: var(--color-paper-2);
|
||||
}
|
||||
|
||||
/* Structured list to the right of each demo (reuses .dna__row from
|
||||
.study-card__dna). Editorial card-on-paper container. */
|
||||
.skill-row__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: var(--space-md) var(--space-lg);
|
||||
display: grid;
|
||||
gap: 0;
|
||||
background: var(--color-paper);
|
||||
border: var(--rule-card, 1px) solid var(--color-rule);
|
||||
border-radius: var(--radius-card, 0);
|
||||
}
|
||||
|
||||
[data-theme="atelier"] .skill-row__list,
|
||||
[data-theme="salon"] .skill-row__list {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
border-block-start: var(--rule-hair) solid var(--color-rule);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
[data-theme="brutal"] .skill-row__list,
|
||||
[data-theme="manifesto"] .skill-row__list { border-width: 2px; }
|
||||
|
||||
.skill-row__list code {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8125em;
|
||||
background: var(--color-paper-2);
|
||||
padding: 0.05em 0.35em;
|
||||
border: var(--rule-hair) solid var(--color-rule);
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
/* Row I — Build demo: brief pill → arrow → output thumb stacked */
|
||||
.skill-row__demo--build {
|
||||
display: grid;
|
||||
gap: var(--space-sm);
|
||||
justify-items: start;
|
||||
}
|
||||
|
||||
.brief-pill {
|
||||
display: inline-block;
|
||||
padding: var(--space-xs) var(--space-md);
|
||||
background: var(--color-paper-2);
|
||||
border: var(--rule-hair) solid var(--color-rule);
|
||||
border-radius: 999px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-xs);
|
||||
color: var(--color-ink-2);
|
||||
font-style: italic;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
[data-theme="brutal"] .brief-pill,
|
||||
[data-theme="manifesto"] .brief-pill,
|
||||
[data-theme="terminal"] .brief-pill,
|
||||
[data-theme="newsprint"] .brief-pill,
|
||||
[data-theme="atelier"] .brief-pill {
|
||||
border-radius: 0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.brief-arrow {
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--text-md);
|
||||
color: var(--color-rule-2);
|
||||
user-select: none;
|
||||
padding-inline-start: var(--space-md);
|
||||
}
|
||||
|
||||
.brief-output {
|
||||
display: block;
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 10;
|
||||
overflow: hidden;
|
||||
border: var(--rule-card, 1px) solid var(--color-rule);
|
||||
}
|
||||
|
||||
.brief-output img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top left;
|
||||
}
|
||||
|
||||
/* Row III — Audit demo: target image with overlay punch-list flags */
|
||||
.skill-row__demo--audit > .fig-corners {
|
||||
display: block;
|
||||
position: relative;
|
||||
aspect-ratio: 16 / 10;
|
||||
overflow: hidden;
|
||||
border: var(--rule-card, 1px) solid var(--color-rule);
|
||||
}
|
||||
|
||||
.skill-row__demo--audit img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top left;
|
||||
}
|
||||
|
||||
.audit-flags {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.audit-flag {
|
||||
position: absolute;
|
||||
top: var(--top);
|
||||
left: var(--left);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.audit-flag__num {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 1.75rem;
|
||||
height: 1.75rem;
|
||||
border-radius: 50%;
|
||||
background: var(--color-accent);
|
||||
color: var(--color-paper);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
box-shadow: 0 0 0 3px var(--color-paper), 0 1px 6px oklch(0% 0 0 / 0.18);
|
||||
}
|
||||
|
||||
[data-theme="manifesto"] .audit-flag__num,
|
||||
[data-theme="brutal"] .audit-flag__num { border-radius: 0; }
|
||||
|
||||
/* Rows IV & V — Diptych: before / after side-by-side thumbnails */
|
||||
.skill-row__demo--diptych {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: var(--space-sm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.diptych__half {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
gap: var(--space-xs);
|
||||
}
|
||||
|
||||
.diptych__half > .fig-corners {
|
||||
display: block;
|
||||
aspect-ratio: 16 / 10;
|
||||
overflow: hidden;
|
||||
border: var(--rule-hair) solid var(--color-rule);
|
||||
}
|
||||
|
||||
.diptych__half img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top left;
|
||||
}
|
||||
|
||||
.diptych__cap {
|
||||
font-family: var(--font-label);
|
||||
font-size: var(--text-xs);
|
||||
letter-spacing: var(--tracking-label);
|
||||
text-transform: uppercase;
|
||||
color: var(--color-muted);
|
||||
font-feature-settings: "tnum";
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
.faq__qletter {
|
||||
font-family: var(--font-display);
|
||||
font-style: var(--display-style, normal);
|
||||
font-weight: var(--display-weight, 500);
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0;
|
||||
text-transform: none;
|
||||
color: var(--color-ink);
|
||||
margin-inline-end: 0.2em;
|
||||
.diptych__half[data-state="after"] .diptych__cap {
|
||||
color: var(--color-accent-ink, var(--color-accent));
|
||||
}
|
||||
|
||||
[data-theme="riso"] .faq__qletter { text-transform: lowercase; }
|
||||
[data-theme="brutal"] .faq__qletter,
|
||||
[data-theme="manifesto"] .faq__qletter,
|
||||
[data-theme="sport"] .faq__qletter { text-transform: uppercase; }
|
||||
|
||||
.faq__q {
|
||||
margin: 0;
|
||||
font-family: var(--font-display);
|
||||
font-weight: var(--display-weight, 500);
|
||||
font-style: var(--display-style, normal);
|
||||
font-size: clamp(1.125rem, 1vw + 0.75rem, 1.5rem);
|
||||
line-height: var(--lh-snug);
|
||||
letter-spacing: var(--tracking-tight);
|
||||
color: var(--color-ink);
|
||||
font-optical-sizing: auto;
|
||||
grid-column: 2;
|
||||
@media (max-width: 40rem) {
|
||||
.skill-row__demo--diptych {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-md);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 50rem) {
|
||||
.faq__q { grid-column: 1; }
|
||||
}
|
||||
|
||||
.faq__a {
|
||||
margin: 0.4rem 0 0;
|
||||
font-family: var(--font-serif);
|
||||
font-style: italic;
|
||||
font-size: 0.9375rem;
|
||||
line-height: var(--lh-normal);
|
||||
color: var(--color-ink-2);
|
||||
max-width: 64ch;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
@media (max-width: 50rem) {
|
||||
.faq__a { grid-column: 1; }
|
||||
}
|
||||
|
||||
.faq__a code {
|
||||
font-family: var(--font-mono);
|
||||
font-style: normal;
|
||||
font-size: 0.875em;
|
||||
background: var(--color-paper-2);
|
||||
padding: 0.05em 0.35em;
|
||||
border: 1px solid var(--color-rule);
|
||||
border-radius: 2px;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.faq__a strong {
|
||||
font-weight: 600;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.faq__a em {
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
[data-theme="brutal"] .faq__a,
|
||||
[data-theme="manifesto"] .faq__a,
|
||||
[data-theme="terminal"] .faq__a,
|
||||
[data-theme="sport"] .faq__a,
|
||||
[data-theme="almanac"] .faq__a,
|
||||
[data-theme="quiet"] .faq__a,
|
||||
[data-theme="bloom"] .faq__a {
|
||||
font-family: var(--font-body);
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[data-theme="manifesto"] .faq__q,
|
||||
[data-theme="brutal"] .faq__q,
|
||||
[data-theme="sport"] .faq__q { text-transform: uppercase; }
|
||||
|
||||
[data-theme="riso"] .faq__q { text-transform: lowercase; }
|
||||
|
||||
/* — 06 · Install pane ——————————————————————————————
|
||||
A single bordered "manual page" card with three numbered rows —
|
||||
I · Run, II · In, III · Then. Replaces the old 4-card grid. The
|
||||
|
||||
+208
-100
@@ -46,7 +46,7 @@
|
||||
<header class="banner" role="banner">
|
||||
<a class="banner__mark" href="#top" aria-label="Hallmark — top of page">
|
||||
<span class="banner__name">Hallmark</span>
|
||||
<span class="banner__ver tnum">v0.9</span>
|
||||
<span class="banner__ver tnum">v1.0</span>
|
||||
</a>
|
||||
|
||||
<a class="banner__install" href="#install" aria-label="Jump to install section">Install</a>
|
||||
@@ -309,64 +309,215 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 03 · STUDY — what `study` extracts from a design -->
|
||||
<section class="section reveal" style="--i:2" id="study" aria-labelledby="s-study">
|
||||
<!-- 03 · SKILLS — five things Hallmark does, one ruleset underneath -->
|
||||
<section class="section reveal" style="--i:2" id="skills" aria-labelledby="s-skills">
|
||||
<header class="section__head">
|
||||
<p class="section-label">
|
||||
<span class="num">03</span><span class="divider">⁄</span><span>Study</span>
|
||||
<span class="num">03</span><span class="divider">⁄</span><span>Skills</span>
|
||||
</p>
|
||||
<h2 class="section__title" id="s-study">
|
||||
What Hallmark sees when it reads a design.
|
||||
<h2 class="section__title" id="s-skills">
|
||||
Five things Hallmark does. One ruleset underneath.
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<p class="study__intro">
|
||||
<code>hallmark study</code> reads a design's structure, not its pixels. Screenshot left, structured DNA right.
|
||||
<p class="skills__intro">
|
||||
Hallmark has one default behaviour and four explicit verbs. Each reads a different input and returns a different shape — same opinions, different jobs.
|
||||
</p>
|
||||
|
||||
<div class="study-grid">
|
||||
<ol class="skills-list">
|
||||
|
||||
<!-- Tile 01 — Tide -->
|
||||
<article class="study-card">
|
||||
<div class="study-card__media">
|
||||
<img class="study-card__img" src="_tests/_thumbs/01-tide.png" alt="Tide — Letter macrostructure on warm cream paper" loading="lazy" decoding="async" />
|
||||
<span class="study-card__badge">01 · Tide</span>
|
||||
<!-- Row I — Build (default) -->
|
||||
<li class="skill-row" data-verb="build">
|
||||
<header class="skill-row__head">
|
||||
<span class="skill-row__num num--roman" aria-hidden="true">I</span>
|
||||
<div class="skill-row__head-body">
|
||||
<h3 class="skill-row__title">Build</h3>
|
||||
<p class="skill-row__lede">Ask for a page. Get a page that doesn't look generated. Hallmark picks a macrostructure first, then dresses it — and refuses to repeat the same shape twice.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="skill-row__body">
|
||||
<figure class="skill-row__demo skill-row__demo--build">
|
||||
<span class="brief-pill" aria-label="Example brief">"Build me a landing page for an indie podcast platform."</span>
|
||||
<span class="brief-arrow" aria-hidden="true">↓</span>
|
||||
<span class="fig-corners brief-output">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/hero-static-hour.jpg" alt="Static Hour — a Hallmark output for an indie-podcast brief" loading="lazy" decoding="async" width="1600" height="968" />
|
||||
</span>
|
||||
</figure>
|
||||
|
||||
<ol class="skill-row__list">
|
||||
<li class="dna__row"><span class="dna__k">Invocation</span><span class="dna__v">(default) — just ask</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Reads</span><span class="dna__v">your brief, project tokens, framework</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Picks</span><span class="dna__v">macrostructure → theme → enrichment</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Returns</span><span class="dna__v">a working page, stamped, slop-tested</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Refuses</span><span class="dna__v">repeating the last 3 macrostructures</span></li>
|
||||
</ol>
|
||||
</div>
|
||||
<ol class="study-card__dna">
|
||||
<li class="dna__row"><span class="dna__k">Macrostructure</span><span class="dna__v">Letter</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Hero archetype</span><span class="dna__v">H5 Letter · salutation + body + signoff</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Display role</span><span class="dna__v">italic editorial serif</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Body role</span><span class="dna__v">italic editorial serif (same family, smaller weight)</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Label role</span><span class="dna__v">small-caps grotesque</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Paper band</span><span class="dna__v">light · warm cream</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Accent hue</span><span class="dna__v">warm orange · ≤ 3% footprint</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Density</span><span class="dna__v">generous · single-column letter</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Pairing logic</span><span class="dna__v">single family carrying the page; mono labels for register</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Rhythm</span><span class="dna__v">left-biased · varied padding · letter-format intimacy</span></li>
|
||||
</ol>
|
||||
</article>
|
||||
</li>
|
||||
|
||||
<!-- Tile 02 — Tracejam -->
|
||||
<article class="study-card">
|
||||
<div class="study-card__media">
|
||||
<img class="study-card__img" src="_tests/_thumbs/05-tracejam.png" alt="Tracejam — Workbench macrostructure on dark charcoal" loading="lazy" decoding="async" />
|
||||
<span class="study-card__badge">02 · Tracejam</span>
|
||||
<!-- Row II — Study (preserves the existing DNA cards as THE demo) -->
|
||||
<li class="skill-row" data-verb="study">
|
||||
<header class="skill-row__head">
|
||||
<span class="skill-row__num num--roman" aria-hidden="true">II</span>
|
||||
<div class="skill-row__head-body">
|
||||
<h3 class="skill-row__title">Study</h3>
|
||||
<p class="skill-row__lede">Paste a design you admire. Hallmark reads its structure, not its pixels — and returns a 10-field DNA card you can build against. Never copies. Never claims to ID fonts.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="skill-row__body skill-row__body--study">
|
||||
<div class="study-grid">
|
||||
<article class="study-card">
|
||||
<div class="study-card__media">
|
||||
<img class="study-card__img" src="_tests/_thumbs/01-tide.png" alt="Tide — Letter macrostructure on warm cream paper" loading="lazy" decoding="async" />
|
||||
<span class="study-card__badge">01 · Tide</span>
|
||||
</div>
|
||||
<ol class="study-card__dna">
|
||||
<li class="dna__row"><span class="dna__k">Macrostructure</span><span class="dna__v">Letter</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Hero archetype</span><span class="dna__v">H5 Letter · salutation + body + signoff</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Display role</span><span class="dna__v">italic editorial serif</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Body role</span><span class="dna__v">italic editorial serif (same family, smaller weight)</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Label role</span><span class="dna__v">small-caps grotesque</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Paper band</span><span class="dna__v">light · warm cream</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Accent hue</span><span class="dna__v">warm orange · ≤ 3% footprint</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Density</span><span class="dna__v">generous · single-column letter</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Pairing logic</span><span class="dna__v">single family carrying the page; mono labels for register</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Rhythm</span><span class="dna__v">left-biased · varied padding · letter-format intimacy</span></li>
|
||||
</ol>
|
||||
</article>
|
||||
|
||||
<article class="study-card">
|
||||
<div class="study-card__media">
|
||||
<img class="study-card__img" src="_tests/_thumbs/05-tracejam.png" alt="Tracejam — Workbench macrostructure on dark charcoal" loading="lazy" decoding="async" />
|
||||
<span class="study-card__badge">02 · Tracejam</span>
|
||||
</div>
|
||||
<ol class="study-card__dna">
|
||||
<li class="dna__row"><span class="dna__k">Macrostructure</span><span class="dna__v">Workbench</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Hero archetype</span><span class="dna__v">H3 Stat-Led · trace number + sticky panel</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Display role</span><span class="dna__v">soft geometric sans · 600</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Body role</span><span class="dna__v">soft geometric sans · 400</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Label role</span><span class="dna__v">monospace · uppercase</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Paper band</span><span class="dna__v">dark · cool charcoal</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Accent hue</span><span class="dna__v">cyan · phosphor-bright · 8% footprint</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Density</span><span class="dna__v">medium · sticky-panel observability layout</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Pairing logic</span><span class="dna__v">sans display + body, mono labels carry the technical register</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Rhythm</span><span class="dna__v">three-step walkthrough · sticky right panel · medium padding</span></li>
|
||||
</ol>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="study-card__dna">
|
||||
<li class="dna__row"><span class="dna__k">Macrostructure</span><span class="dna__v">Workbench</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Hero archetype</span><span class="dna__v">H3 Stat-Led · trace number + sticky panel</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Display role</span><span class="dna__v">soft geometric sans · 600</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Body role</span><span class="dna__v">soft geometric sans · 400</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Label role</span><span class="dna__v">monospace · uppercase</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Paper band</span><span class="dna__v">dark · cool charcoal</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Accent hue</span><span class="dna__v">cyan · phosphor-bright · 8% footprint</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Density</span><span class="dna__v">medium · sticky-panel observability layout</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Pairing logic</span><span class="dna__v">sans display + body, mono labels carry the technical register</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Rhythm</span><span class="dna__v">three-step walkthrough · sticky right panel · medium padding</span></li>
|
||||
</ol>
|
||||
</article>
|
||||
</li>
|
||||
|
||||
</div>
|
||||
<!-- Row III — Audit -->
|
||||
<li class="skill-row" data-verb="audit">
|
||||
<header class="skill-row__head">
|
||||
<span class="skill-row__num num--roman" aria-hidden="true">III</span>
|
||||
<div class="skill-row__head-body">
|
||||
<h3 class="skill-row__title">Audit</h3>
|
||||
<p class="skill-row__lede">Point Hallmark at a page. Get a ranked punch list of what's wrong — scored against the anti-pattern catalogue. <strong>No edits.</strong> Just the diagnosis.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="skill-row__body">
|
||||
<figure class="skill-row__demo skill-row__demo--audit">
|
||||
<span class="fig-corners">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/verb-audit.png" alt="Audited target page — generic AI-slop landing" loading="lazy" decoding="async" width="1024" height="640" />
|
||||
<ol class="audit-flags" aria-label="Punch list overlaid on the target">
|
||||
<li class="audit-flag" style="--top:24%; --left:50%"><span class="audit-flag__num tnum">1</span></li>
|
||||
<li class="audit-flag" style="--top:51%; --left:48%"><span class="audit-flag__num tnum">2</span></li>
|
||||
<li class="audit-flag" style="--top:67%; --left:50%"><span class="audit-flag__num tnum">3</span></li>
|
||||
</ol>
|
||||
</span>
|
||||
</figure>
|
||||
|
||||
<ol class="skill-row__list">
|
||||
<li class="dna__row"><span class="dna__k">Invocation</span><span class="dna__v"><code>hallmark audit <target></code></span></li>
|
||||
<li class="dna__row"><span class="dna__k"><span class="tnum">1</span> · Display</span><span class="dna__v">Inter-as-display · the AI-default tell</span></li>
|
||||
<li class="dna__row"><span class="dna__k"><span class="tnum">2</span> · Hierarchy</span><span class="dna__v">centred everything · no asymmetry</span></li>
|
||||
<li class="dna__row"><span class="dna__k"><span class="tnum">3</span> · Accent</span><span class="dna__v">purple-to-blue gradient · over-applied</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Returns</span><span class="dna__v">ranked findings, not edits</span></li>
|
||||
</ol>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Row IV — Refine -->
|
||||
<li class="skill-row" data-verb="refine">
|
||||
<header class="skill-row__head">
|
||||
<span class="skill-row__num num--roman" aria-hidden="true">IV</span>
|
||||
<div class="skill-row__head-body">
|
||||
<h3 class="skill-row__title">Refine</h3>
|
||||
<p class="skill-row__lede">Layout's fine. The details aren't. Hallmark polishes in place — smallest possible diff, layout preserved, no redesign.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="skill-row__body">
|
||||
<figure class="skill-row__demo skill-row__demo--diptych">
|
||||
<figure class="diptych__half" data-state="before">
|
||||
<span class="fig-corners">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/verb-audit.png" alt="Same content before refinement — centered, generic" loading="lazy" decoding="async" width="1024" height="640" />
|
||||
</span>
|
||||
<figcaption class="diptych__cap">Before</figcaption>
|
||||
</figure>
|
||||
<figure class="diptych__half" data-state="after">
|
||||
<span class="fig-corners">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/verb-refine.png" alt="Same content after Hallmark refine — left-biased, italic display, real proof quote" loading="lazy" decoding="async" width="1024" height="640" />
|
||||
</span>
|
||||
<figcaption class="diptych__cap">After refine</figcaption>
|
||||
</figure>
|
||||
</figure>
|
||||
|
||||
<ol class="skill-row__list">
|
||||
<li class="dna__row"><span class="dna__k">Invocation</span><span class="dna__v"><code>hallmark refine <target></code></span></li>
|
||||
<li class="dna__row"><span class="dna__k">Preserves</span><span class="dna__v">layout · copy · brand</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Touches</span><span class="dna__v">type pairing · accent · spacing · proof</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Returns</span><span class="dna__v">smallest possible diff</span></li>
|
||||
</ol>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<!-- Row V — Redesign -->
|
||||
<li class="skill-row" data-verb="redesign">
|
||||
<header class="skill-row__head">
|
||||
<span class="skill-row__num num--roman" aria-hidden="true">V</span>
|
||||
<div class="skill-row__head-body">
|
||||
<h3 class="skill-row__title">Redesign</h3>
|
||||
<p class="skill-row__lede">Same content. Same brand. Different bones. Hallmark throws out the structural fingerprint and rebuilds with a deliberately different one — new section rhythm, new heading placement, new component voice.</p>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="skill-row__body">
|
||||
<figure class="skill-row__demo skill-row__demo--diptych">
|
||||
<figure class="diptych__half" data-state="before">
|
||||
<span class="fig-corners">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/verb-refine.png" alt="A split-hero macrostructure" loading="lazy" decoding="async" width="1024" height="640" />
|
||||
</span>
|
||||
<figcaption class="diptych__cap">Split hero</figcaption>
|
||||
</figure>
|
||||
<figure class="diptych__half" data-state="after">
|
||||
<span class="fig-corners">
|
||||
<span class="fig-corners__bl"></span><span class="fig-corners__br"></span>
|
||||
<img src="_tests/_thumbs/verb-redesign.png" alt="A long-document macrostructure with the same brand voice" loading="lazy" decoding="async" width="1024" height="640" />
|
||||
</span>
|
||||
<figcaption class="diptych__cap">Long document</figcaption>
|
||||
</figure>
|
||||
</figure>
|
||||
|
||||
<ol class="skill-row__list">
|
||||
<li class="dna__row"><span class="dna__k">Invocation</span><span class="dna__v"><code>hallmark redesign <target></code></span></li>
|
||||
<li class="dna__row"><span class="dna__k">Preserves</span><span class="dna__v">copy · brand · information architecture</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Replaces</span><span class="dna__v">macrostructure · heading placement · rhythm</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Mood</span><span class="dna__v"><code>--mood <name></code> optional override</span></li>
|
||||
<li class="dna__row"><span class="dna__k">Returns</span><span class="dna__v">structurally different page from same brief</span></li>
|
||||
</ol>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<!-- 04 · WITHOUT / WITH — same copy, two design languages, four examples -->
|
||||
@@ -664,59 +815,13 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 06 · FAQ — five typographic Q/A pairs -->
|
||||
<section class="section reveal" style="--i:5" id="faq" aria-labelledby="s6">
|
||||
<!-- 06 · INSTALL — one command, every harness -->
|
||||
<section class="section reveal" style="--i:5" id="install" aria-labelledby="s6">
|
||||
<header class="section__head">
|
||||
<p class="section-label">
|
||||
<span class="num">06</span><span class="divider">⁄</span><span>FAQ</span>
|
||||
<span class="num">06</span><span class="divider">⁄</span><span>Install</span>
|
||||
</p>
|
||||
<h2 class="section__title" id="s6">
|
||||
The questions people actually ask.
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
<ol class="faq" role="list">
|
||||
|
||||
<li class="faq__row">
|
||||
<p class="faq__q-mark"><span class="faq__qletter">Q</span> ⁄ 01</p>
|
||||
<h3 class="faq__q">Does it work with Cursor and Codex?</h3>
|
||||
<p class="faq__a">Yes. Drop the body of <code>SKILL.md</code> into <code>.cursor/rules/hallmark.mdc</code> for Cursor, or copy the <code>skill/</code> folder into your Codex agent config. Claude Code picks it up at <code>~/.claude/skills/hallmark/</code>.</p>
|
||||
</li>
|
||||
|
||||
<li class="faq__row">
|
||||
<p class="faq__q-mark"><span class="faq__qletter">Q</span> ⁄ 02</p>
|
||||
<h3 class="faq__q">Can I disable a specific rule?</h3>
|
||||
<p class="faq__a">Most rules are universal — typography discipline, accessibility, anti-purple-text-gradient. Genre-specific rules can be loosened by picking a different genre: <em>atmospheric</em> allows dark-canvas radial gradients that <em>editorial</em> bans; <em>modern-minimal</em> allows pure white that <em>editorial</em> bans.</p>
|
||||
</li>
|
||||
|
||||
<li class="faq__row">
|
||||
<p class="faq__q-mark"><span class="faq__qletter">Q</span> ⁄ 03</p>
|
||||
<h3 class="faq__q">What if I want my brand colours, not the catalog?</h3>
|
||||
<p class="faq__a">Mention them in the brief, or attach a brand colour. Hallmark's <strong>custom-theme</strong> route builds an OKLCH palette tuned to your anchor and pairs free fonts to it — full rules still apply, just on your colours.</p>
|
||||
</li>
|
||||
|
||||
<li class="faq__row">
|
||||
<p class="faq__q-mark"><span class="faq__qletter">Q</span> ⁄ 04</p>
|
||||
<h3 class="faq__q">What does "AI-slop" mean exactly?</h3>
|
||||
<p class="faq__a">Twenty-one named tells the LLM reaches for by default — purple-gradient hero, centred-everything, icon-tile feature row, glass card, gradient headline, pill button with gradient fill. Run <code>hallmark audit</code> on any page to see them flagged.</p>
|
||||
</li>
|
||||
|
||||
<li class="faq__row">
|
||||
<p class="faq__q-mark"><span class="faq__qletter">Q</span> ⁄ 05</p>
|
||||
<h3 class="faq__q">Five verbs — what do they do?</h3>
|
||||
<p class="faq__a"><code>hallmark</code> (default) builds. <code>hallmark audit</code> scores existing code. <code>hallmark refine</code> polishes in place. <code>hallmark redesign</code> rethinks structure — and on a whole project, writes a <code>design.md</code> first so every page shares the system. <code>hallmark study</code> reads a screenshot you admire and extracts its DNA, never the pixels.</p>
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<!-- 07 · INSTALL — one command, every harness -->
|
||||
<section class="section reveal" style="--i:6" id="install" aria-labelledby="s7">
|
||||
<header class="section__head">
|
||||
<p class="section-label">
|
||||
<span class="num">07</span><span class="divider">⁄</span><span>Install</span>
|
||||
</p>
|
||||
<h2 class="section__title" id="s7">
|
||||
One command. Works in every harness.
|
||||
</h2>
|
||||
</header>
|
||||
@@ -761,7 +866,7 @@
|
||||
</div>
|
||||
</section>
|
||||
<!-- FOOTER SLOT — archetype swaps per theme -->
|
||||
<footer class="slot slot--foot reveal" data-slot="footer" style="--i:7" role="contentinfo" aria-label="Colophon">
|
||||
<footer class="slot slot--foot reveal" data-slot="footer" style="--i:6" role="contentinfo" aria-label="Colophon">
|
||||
</footer>
|
||||
|
||||
</main>
|
||||
@@ -853,9 +958,12 @@
|
||||
<div class="hero hero--photo">
|
||||
<div class="hero__photo" aria-hidden="true">
|
||||
<div class="hero__photo-grid">
|
||||
<span></span><span></span><span></span>
|
||||
<span></span><span></span><span></span>
|
||||
<span></span><span></span><span></span>
|
||||
<span><img src="_tests/_thumbs/hero-static-hour.jpg" alt="" loading="lazy" decoding="async" width="1600" height="968" /></span>
|
||||
<span><img src="_tests/_thumbs/hero-najm.jpg" alt="" loading="lazy" decoding="async" width="1600" height="853" /></span>
|
||||
<span><img src="_tests/_thumbs/hero-tally-hero.jpg" alt="" loading="lazy" decoding="async" width="1600" height="867" /></span>
|
||||
<span><img src="_tests/_thumbs/hero-nexus.jpg" alt="" loading="lazy" decoding="async" width="1600" height="862" /></span>
|
||||
<span><img src="_tests/_thumbs/05-tracejam.png" alt="" loading="lazy" decoding="async" width="1024" height="640" /></span>
|
||||
<span><img src="_tests/_thumbs/hero-tally-process.jpg" alt="" loading="lazy" decoding="async" width="1600" height="868" /></span>
|
||||
</div>
|
||||
<span class="hero__photo-caption">{{captionA}} · {{captionB}}</span>
|
||||
</div>
|
||||
@@ -974,7 +1082,7 @@
|
||||
<ul>
|
||||
<li><span class="foot__powered-mark">Together AI</span></li>
|
||||
<li>MIT licensed</li>
|
||||
<li>v0.9.0</li>
|
||||
<li>v1.0.0</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+6
-6
@@ -112,7 +112,7 @@ const THEME_GENRES = {
|
||||
// playful — post-Linear soft school (2 themes)
|
||||
pastel: "playful",
|
||||
plume: "playful",
|
||||
// editorial — open-design-inspired premium (added v0.9.0)
|
||||
// editorial — open-design-inspired premium (added v1.0.0)
|
||||
editorial: "editorial",
|
||||
};
|
||||
|
||||
@@ -368,7 +368,7 @@ const COPY = {
|
||||
captionB: "LAP 12",
|
||||
},
|
||||
studio: {
|
||||
eyebrow: "Studio · 2026 selected work",
|
||||
eyebrow: "Studio · 2026",
|
||||
title: HERO_TITLE,
|
||||
lede: "We design and build distinctive products for ambitious teams. Hallmark is our typography opinion, codified — fifteen themes, twenty-one shapes, no defaults.",
|
||||
ctaLabel: "Engage",
|
||||
@@ -447,7 +447,7 @@ const COPY = {
|
||||
letterBody: "A theme for the modern enterprise page — the Stripe / Linear / ElevenLabs school of restraint. Clean white, confident typography, pill CTAs. Minimalism with conviction, not absence.",
|
||||
signoff: "Yours,",
|
||||
captionA: "Quiet",
|
||||
captionB: "v0.9",
|
||||
captionB: "v1.0",
|
||||
},
|
||||
bloom: {
|
||||
eyebrow: "Atmospheric · 2026",
|
||||
@@ -489,7 +489,7 @@ const COPY = {
|
||||
letterBody: "The polished-SaaS school of restraint, but warmer. Warm-grey paper instead of pure white; coral accent on focus rings and small marks. Pill CTAs, two-column heroes, generous space.",
|
||||
signoff: "Yours,",
|
||||
captionA: "Coral",
|
||||
captionB: "v0.9",
|
||||
captionB: "v1.0",
|
||||
},
|
||||
violet: {
|
||||
eyebrow: "Modern minimal · quiet violet",
|
||||
@@ -510,7 +510,7 @@ const COPY = {
|
||||
letterBody: "A modern minimal theme tuned for dev tools and platforms. Near-white paper, near-black ink, single quiet violet accent on focus rings. Tight Geist throughout — letterspacing pulled in, type-led hierarchy, no ornament.",
|
||||
signoff: "Yours,",
|
||||
captionA: "Violet",
|
||||
captionB: "v0.9",
|
||||
captionB: "v1.0",
|
||||
},
|
||||
aurora: {
|
||||
eyebrow: "Atmospheric · cool",
|
||||
@@ -634,7 +634,7 @@ function buildDenseColophon(themeName) {
|
||||
// template-string'd so it stays monospace-aligned.
|
||||
const today = "2026-05-01";
|
||||
return [
|
||||
`# hallmark · v0.9.0 · ${themeName.toLowerCase()}`,
|
||||
`# hallmark · v1.0.0 · ${themeName.toLowerCase()}`,
|
||||
`# build: ${today} · MIT · powered by together ai`,
|
||||
`#`,
|
||||
`# stats: 21 macros · 40 archetypes · 9 navs · 8 footers · 23 themes · 55 gates`,
|
||||
|
||||
+22
-6
@@ -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.9.0
|
||||
version: 1.0.0
|
||||
---
|
||||
|
||||
# Hallmark
|
||||
@@ -34,6 +34,22 @@ The default Design flow always picks a theme. By default it picks one of the **2
|
||||
|
||||
---
|
||||
|
||||
## Disciplines that hold across every verb
|
||||
|
||||
These four disciplines are **not** verb-specific. They apply to default Design, `audit`, `refine`, `redesign`, `study`, and component-scope alike. They sit alongside the slop test, not inside one branch of it.
|
||||
|
||||
1. **Pre-emit self-critique.** Before handing back any output, score it 1–5 on six axes — Philosophy, Hierarchy, Execution, Specificity, Restraint, Variety. Anything **< 3** triggers a revision pass. Stamp the six scores at the top of the artifact (`/* Hallmark · pre-emit critique: P5 H4 E5 S4 R5 V5 */`). See [`references/slop-test.md`](references/slop-test.md) § Pre-emit self-critique.
|
||||
|
||||
2. **Honest copy — no fabricated content.** If the user did not supply a metric, do not invent one. Stat-led layouts, comparison rows, and proof bars must use real numbers, a placeholder (`—` plus a labelled grey block, "metric to confirm"), or a different macrostructure. *"+47 % conversion"*, *"trusted by 50,000+ teams"*, and *"10× faster"* are slop the moment they're invented. Same rule for testimonials, logos, and case-study counts. See [`references/anti-patterns.md` § Invented metrics](references/anti-patterns.md) and slop-test gate **56**.
|
||||
|
||||
3. **Locked tokens — no mid-render improvisation.** Once a theme is selected at Step 2.6, every colour and every `font-family` declaration in the artifact must reference a named token (`var(--color-accent)`, `font-family: var(--font-display)`). Inline OKLCH / hex / `rgb()` values, or a `font-family: "Some Font"` declaration that bypasses the token block, are not allowed. If a value is needed that doesn't exist as a token, lift it into the token block as a new named variable, then reference it. See [`references/anti-patterns.md` § Mid-render token improvisation](references/anti-patterns.md) and slop-test gate **58**.
|
||||
|
||||
4. **Re-drawn chrome forbidden.** Hallmark must not hand-build fake browser bars (URL pill + traffic-light dots), fake phone frames, fake code-block windows (mock title bar + dots wrapping a `<pre>`), or fake IDE chrome — the user's environment already supplies real chrome. Use real screenshots wrapped in a `<figure>` (with at most a hairline border), or omit the chrome and let the content stand on its own. See [`references/anti-patterns.md` § Re-drawn UI chrome](references/anti-patterns.md) and slop-test gate **57**.
|
||||
|
||||
5. **Clickable text never wraps.** Buttons, primary nav links, footer links, breadcrumbs, and CTAs must read on a single line at every viewport between 320 px and 1920 px. The fix is, in order: shorten the label (most CTA labels are 30–40 % too long), `white-space: nowrap` and let the parent reflow, hide low-priority items at narrow widths, or collapse the nav into a sheet. See [`references/responsive.md` § Clickable text — never wraps](references/responsive.md) and slop-test gate **59**.
|
||||
|
||||
---
|
||||
|
||||
## When the brief is a component, not a page
|
||||
|
||||
Before entering the full Design flow, **check scope**. If any of these fire, run the Component-scope flow instead — most day-to-day dev requests are component-shaped, not page-shaped, and the page-level apparatus (macrostructure, hero enrichment, footer archetype, project memory) is wrong for them.
|
||||
@@ -358,7 +374,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
|
||||
**Format** (Markdown bullets, not ASCII boxes — they render reliably across every chat client and terminal):
|
||||
|
||||
```markdown
|
||||
**Hallmark · v0.9.0**
|
||||
**Hallmark · v1.0.0**
|
||||
|
||||
- **Macrostructure** · Stat-Led
|
||||
- **Theme** · Plain (#fff paper · cool greys · ink-blue accent)
|
||||
@@ -382,7 +398,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
|
||||
**Three more sample preview blocks** for the model to imitate, varied across macrostructure types:
|
||||
|
||||
*Long Document (editorial, motion-cut):*
|
||||
> **Hallmark · v0.9.0**
|
||||
> **Hallmark · v1.0.0**
|
||||
>
|
||||
> - **Macrostructure** · Long Document
|
||||
> - **Theme** · Linen (cool slate paper · steel-blue accent · geometric sans)
|
||||
@@ -393,7 +409,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
|
||||
> - **Diversification** · first run for this project
|
||||
|
||||
*Bento Grid (SaaS, motion-on):*
|
||||
> **Hallmark · v0.9.0**
|
||||
> **Hallmark · v1.0.0**
|
||||
>
|
||||
> - **Macrostructure** · Bento Grid
|
||||
> - **Theme** · Pastel (light cool paper · indigo accent · geometric Geist)
|
||||
@@ -404,7 +420,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
|
||||
> - **Diversification** · differs from Plain on paper hue (light-cool vs pure-white) + accent (indigo vs ink-blue)
|
||||
|
||||
*Manifesto (declarative, no enrichment):*
|
||||
> **Hallmark · v0.9.0**
|
||||
> **Hallmark · v1.0.0**
|
||||
>
|
||||
> - **Macrostructure** · Manifesto
|
||||
> - **Theme** · Manifesto (dark · Inter Tight 900 · single red bleed)
|
||||
@@ -415,7 +431,7 @@ Before emitting any code, output a tight summary of what you're about to ship. T
|
||||
> - **Diversification** · differs from Linen on paper band (dark vs light) + display style (display-heavy vs geometric-sans)
|
||||
|
||||
*Custom (Coffeebox archival café):*
|
||||
> **Hallmark · v0.9.0**
|
||||
> **Hallmark · v1.0.0**
|
||||
>
|
||||
> - **Macrostructure** · Long Document
|
||||
> - **Theme** · custom (vibe: "archival warmth, hand-set, no varnish" · paper oklch(94% 0.020 65) · accent oklch(58% 0.16 35) terracotta · Fraunces italic display + Source Serif 4 body)
|
||||
|
||||
@@ -182,12 +182,52 @@ Material Icons in the navbar, Heroicons in the feature cards, Lucide in the foot
|
||||
|
||||
### AI-illustration look
|
||||
|
||||
Smooth-mesh-blob characters with no joint articulation, mid-2010s "modern flat" stock poses, unmistakably-Midjourney compositions with the symmetric default lighting.
|
||||
Smooth-mesh-blob characters with no joint articulation, mid-2010s "modern flat" stock poses, unmistakably-Midjourney compositions with the symmetric default lighting. Hand-drawn SVG humans (the "doodle person with one eye larger than the other") fall under this — corporate-doodle is the late-2010s Slack/Figma marketing template, and the audience reads it as AI immediately.
|
||||
|
||||
**Why it fails.** It reads as AI in milliseconds. The 2026 audience pattern-matches this faster than any other tell.
|
||||
|
||||
**Fix.** Hand-build the illustration in pure CSS or SVG (Tier A or B in [`hero-enrichment.md`](hero-enrichment.md)). If you must generate, use Nanobanana 2 or Recraft V4 with reference images, asymmetric crop, and grain post-processing — never raw output. See [`custom-craft.md`](custom-craft.md) Tier E.
|
||||
|
||||
### Invented metrics
|
||||
|
||||
A stat-led layout, comparison row, or proof bar carrying numbers the user never supplied — "10× faster", "saves 5 hours per week", "trusted by 50,000+ teams", "99.9 % uptime", "+47 % conversion". The model reached for a stat to fill a stat slot and made one up.
|
||||
|
||||
**Why it fails.** Audiences read invented stats as fast as they read invented testimonials. A page that lies on its proof bar can't be trusted on its claims either, and the AI tell is unmistakable: every fabricated number reads "this was generated, not written".
|
||||
|
||||
**Fix.** Three options, in order of preference: (1) replace the number with `—` and a labelled grey block ("metric to confirm" or "stat pending"); (2) ask the user for the real number and pause the run; (3) rebuild the section without the proof slot — a stat-led macrostructure with no real stats is the wrong macrostructure. The number-shaped hole is honest; the fabricated number is slop. *(Slop-test gate 56.)*
|
||||
|
||||
### Generic emoji as feature icon
|
||||
|
||||
A feature card, value prop, step number, or pricing tier with `✨` `🚀` `⚡` `🔥` `🎯` `✅` rendered as the primary icon. The "sparkle hero" badge with a `✨` glyph beside the eyebrow. Emoji standing in for an icon library because the model didn't pick one.
|
||||
|
||||
**Why it fails.** Emoji are typography of a sort, but they are not part of the page's typographic system — they're rendered by the OS and look different on every device, they break the icon's stroke voice (you've now mixed a Phosphor-style line icon with a Twemoji blob), and the choice is recognisably the AI default. Sparkle-emoji-as-AI-shortcut is the cliché of the 2024–2025 era.
|
||||
|
||||
**Fix.** Pick a single icon library and ship it ([assets.md](assets.md) names the canon). Or build a custom SVG mark. Or omit the icon entirely and lead with typography — most feature lists don't need icons. *(Slop-test gate 60.)*
|
||||
|
||||
### Re-drawn UI chrome
|
||||
|
||||
A fake browser bar (URL pill + traffic-light dots) wrapping a screenshot. A fake phone frame (rounded rectangle + notch + speaker slit) around a mobile mockup. A fake code-block window (mock title bar + close/minimise dots) wrapping a `<pre>`. A fake IDE chrome (file tabs + activity bar) around an editor screenshot. All hand-built in HTML/CSS or SVG.
|
||||
|
||||
**Why it fails.** The user already has the chrome — their browser, their phone, their IDE all *are* chrome. Redrawing it in a page is like printing a photograph of a picture frame inside a real picture frame. The fakery is also bad: the URL is wrong, the dots aren't macOS dots, the notch is the wrong shape. Audiences pattern-match re-drawn chrome as "AI invented a UI that already exists" within a glance.
|
||||
|
||||
**Fix.** Use a real screenshot wrapped in `<figure>` (with a hairline border at most). For phone mockups, use a transparent-PNG device frame from a vendor or a real product photograph — never a CSS-drawn one. For code blocks, use the system `<pre>` with a typographic frame (top rule + label + bottom rule), not a faked window-chrome. The page's job is to show content, not to imitate the OS. *(Slop-test gate 57.)*
|
||||
|
||||
### Mid-render token improvisation
|
||||
|
||||
A theme is selected at the top of the run, but the artifact contains inline colour values (`#5b6cff`, `oklch(74% 0.18 245)`, `rgb(...)`) or `font-family` declarations that aren't drawn from the token block. Or: the artifact ships with the theme's token set *plus* one extra hex tucked into a hover state, a focus ring, or a single border. The model picked the theme, then drifted.
|
||||
|
||||
**Why it fails.** Token discipline is the difference between a system and a freestyle. Once a theme is locked, every colour and every font in the file must reference a named token (`var(--color-accent)`, `font-family: var(--font-display)`). Inline values are how cohesion erodes — by the third edit pass, the page has eight colours instead of three, and the editorial restraint that made the theme work is gone. Audiences don't see the inline value, but they feel the looseness.
|
||||
|
||||
**Fix.** Every colour and every font in the artifact must come through `var(--token-name)`. If you need a value that doesn't exist as a token, add it to the token block first (`--color-accent-warm: oklch(...)`) and then reference it. Inline OKLCH or one-off hex values mid-render are not allowed. *(Slop-test gate 58. See also [SKILL.md § Locked tokens](../SKILL.md).)*
|
||||
|
||||
### Wrap-to-two-lines clickable text
|
||||
|
||||
A button label, nav link, footer link, breadcrumb, or CTA reads on two lines because the viewport got narrow and the label was long. Visually, the affordance now looks broken — readers can't tell whether the line break is intentional. Worst case: the second line is one word ("free", "more", "started"), which reads as a styling error.
|
||||
|
||||
**Why it fails.** Clickable affordances are one-line objects. The reader scans the label, decides whether to click, moves on. A two-line label slows the scan, breaks the row's vertical rhythm (button height grows, sibling buttons stay the same), and signals "this page wasn't tested at this width". It's a responsive-discipline tell.
|
||||
|
||||
**Fix.** In order of preference: (1) shorten the label — *"Get started free" → "Start free"*; *"Read the documentation" → "Read docs"*. Most CTA labels are too long. (2) Set `white-space: nowrap` on the affordance and let the parent flex container reflow. (3) Drop a non-essential nav item at narrow widths via `hidden=until-found` or `display: none`. (4) Collapse the nav into a sheet/menu under a threshold. *Never* let a primary CTA or nav link wrap. *(Slop-test gate 59. See [responsive.md § Clickable text — never wraps](responsive.md).)*
|
||||
|
||||
### Lottie shortcut
|
||||
|
||||
Reaching for a LottieFiles community animation — the spinning logo, the checkmark draw, the loading spinner, the "loading dots" loop — when pure CSS or hand-built SVG would have produced it stronger and lighter.
|
||||
|
||||
@@ -42,6 +42,39 @@ h1 { font-size: clamp(2.5rem, 4vw + 1rem, 6rem); }
|
||||
|
||||
Never build a mouse-hover interaction that has no touch equivalent.
|
||||
|
||||
## Clickable text — never wraps
|
||||
|
||||
Buttons, primary nav links, footer links, tab labels, breadcrumbs, and CTAs must read as **single-line affordances at every viewport between 320 px and 1920 px**. A button or nav link wrapping to two lines looks broken — visitors read it as a styling error, not as intentional. The shortest fix is almost always to shorten the label.
|
||||
|
||||
```css
|
||||
/* Affordances are single-line — let the parent reflow, not the label. */
|
||||
.btn,
|
||||
.nav__link,
|
||||
.foot__link,
|
||||
.cta {
|
||||
white-space: nowrap;
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
/* When the row can't fit, collapse the row, not the labels. */
|
||||
@media (max-width: 40rem) {
|
||||
.nav__rail { display: none; } /* desktop nav hides */
|
||||
.nav__sheet-toggle { display: grid; } /* mobile menu shows */
|
||||
}
|
||||
```
|
||||
|
||||
**Order of fixes**, when something does wrap:
|
||||
|
||||
1. **Shorten the label.** *"Get started free"* → *"Start free"*. *"Read the documentation"* → *"Read docs"*. *"Schedule a demo"* → *"Book demo"*. Most CTA labels are 30–40 % longer than they need to be.
|
||||
2. **`white-space: nowrap`** on the affordance, let the parent flex/grid reflow.
|
||||
3. **`hidden=until-found`** the lowest-priority nav item at narrow widths (it remains in DOM for find-in-page and SEO).
|
||||
4. **Collapse the nav** into a sheet / off-canvas / disclosure menu below a content-driven breakpoint.
|
||||
|
||||
**Never:** let a primary CTA or top-level nav link wrap. Long footer-link labels can wrap *only* in a footer column where wrapping is part of the column's rhythm — not in the inline footer link strip (Ft2).
|
||||
|
||||
This is gate **59** in [`slop-test.md`](slop-test.md). Audit any output that ships interactive affordances and confirm none wrap at the breakpoints listed above.
|
||||
|
||||
## Viewport units
|
||||
|
||||
- Use `dvh` / `svh` / `lvh` instead of `vh` for heights that interact with mobile chrome.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Slop test — 55 gates
|
||||
# Slop test — 60 gates + pre-emit self-critique
|
||||
|
||||
Run this list before handing back any output. Every answer must be **no**. Update the Step 5 preview block's `Slop test` row to reflect the actual outcome of this run.
|
||||
|
||||
@@ -6,6 +6,25 @@ Some gates are **universal** (apply to every genre); some are **genre-scoped** (
|
||||
|
||||
---
|
||||
|
||||
## Pre-emit self-critique (six axes)
|
||||
|
||||
Run this **before** the gate list, not after. Score the planned output 1–5 on each axis. Anything **< 3 on any axis triggers a revision pass** before the gate sweep — don't bring known weakness into a sixty-gate review.
|
||||
|
||||
Two passes is normal. Three is a sign the brief is wrong, not the design — re-read the brief.
|
||||
|
||||
| # | Axis | What you're scoring |
|
||||
|---|---|---|
|
||||
| **A** | **Philosophy** | Is there a clear *why* — a position the page is taking? Or is it just a layout? |
|
||||
| **B** | **Hierarchy** | Can a reader tell, in 2 seconds, what's primary, secondary, tertiary? Or is everything the same weight? |
|
||||
| **C** | **Execution** | Are the details (rule weight, accent footprint, text-wrap, focus rings, contrast) all in spec, or is there sloppiness even if the bones are right? |
|
||||
| **D** | **Specificity** | Does this look like *this brief* — or does it look like a generic "page that could be anyone"? |
|
||||
| **E** | **Restraint** | Have you removed everything that isn't earning its place? Decoration, redundancy, padding-for-padding's-sake? |
|
||||
| **F** | **Variety** | Does this output share a structural fingerprint with a previous Hallmark output in the project? Score by structural distance, not visual distance — colour-swaps don't count as variety. |
|
||||
|
||||
Record the six scores in a one-line stamp comment at the top of the file: `/* Hallmark · pre-emit critique: P5 H4 E5 S4 R5 V5 */`. Future runs should be able to find this and avoid repeating the same weakness.
|
||||
|
||||
---
|
||||
|
||||
## Visual
|
||||
|
||||
1. Is the display font Inter, Roboto, Open Sans, Poppins, Lato, or a system default?
|
||||
@@ -129,6 +148,34 @@ Universal — apply to every genre. These gates catch the most-recognised AI fin
|
||||
|
||||
The CSS stamp at Step 6 should record the result alongside contrast: `· nav: N# · footer: Ft# · slop: pass (51–55)`. If any of 51–55 fail, fix before shipping.
|
||||
|
||||
## Honest copy · no fabricated content
|
||||
|
||||
Universal — apply to every genre. The page must not invent facts about the user's product, team, or market.
|
||||
|
||||
56. **Invented metric.** Does the page contain any quantitative claim — "10× faster", "saves 5 hours per week", "trusted by 50,000+ teams", "99.9 % uptime", "+47 % conversion" — that the user did not supply, that has no source, and that the model fabricated to fill a stat-led layout, comparison row, or proof bar? If yes, fail. The fix is one of: replace the number with `—` and a labelled grey block, replace it with a question to the user ("metric to confirm"), or rebuild the section without the proof slot. Stat-led macrostructures are slop the moment their stats become decorative. *(See [anti-patterns.md § Invented metrics](anti-patterns.md).)*
|
||||
|
||||
## Re-drawn UI chrome
|
||||
|
||||
Universal. Hallmark must reuse the user's existing chrome (browser, OS, IDE) instead of redrawing it.
|
||||
|
||||
57. **Re-drawn chrome.** Did Hallmark hand-build a fake browser bar (URL pill + traffic-light dots), a fake phone frame (rounded rectangle + notch + speaker slit), a fake code-block frame (mock window-chrome around a `<pre>`), a fake terminal frame, or a fake IDE chrome (file tabs + activity bar + sidebar) using HTML/CSS or SVG? If yes, fail. Re-drawn chrome is one of the strongest "looks AI-generated" tells — the model invented a UI that already exists in the user's environment. The fix: use a `<picture>` or `<figure>` containing a real screenshot, or omit the chrome and let the content stand on its own. *(See [anti-patterns.md § Re-drawn UI chrome](anti-patterns.md).)*
|
||||
|
||||
## Token discipline
|
||||
|
||||
Universal. The theme picks the palette and font stack at the top of the run; the rest of the run consumes tokens, never invents them.
|
||||
|
||||
58. **Mid-render token improvisation.** Did Hallmark introduce any colour value (`#hex`, `oklch(...)`, `rgb(...)`, `hsl(...)`) or `font-family` declaration *outside* the design tokens defined in `:root` / `[data-theme="..."]`? If yes, fail. Every colour and every font in the artifact must reference a named token (`var(--color-accent)`, `font-family: var(--font-display)`). Inline OKLCH or one-off hexes are mid-render improvisation — the model picked the theme, then forgot it and freestyled. The fix: lift the value into the token block as a new named variable, or replace it with an existing token. *(See [SKILL.md § Locked tokens](../SKILL.md) and [anti-patterns.md § Mid-render token improvisation](anti-patterns.md).)*
|
||||
|
||||
## Responsive — clickable affordances
|
||||
|
||||
Universal. Buttons, links, and nav items must remain readable as single-line affordances when the viewport shrinks.
|
||||
|
||||
59. **Two-line clickable text.** Does any button label, primary nav link, footer link, tab label, breadcrumb, or CTA text wrap to two or more lines at any viewport between 320 px and 1920 px? If yes, fail. Clickable text reading on two lines looks broken — visitors read it as a styling error, not as intentional. The fix is one of: shorten the label (the best fix; "Get started free" → "Start free"), set `white-space: nowrap` on the affordance and let the parent reflow, drop a non-essential nav item at narrow widths via `hidden=until-found`, or collapse the nav into a sheet/menu. Never let a CTA or nav link wrap. *(See [responsive.md § Clickable text — never wraps](responsive.md).)*
|
||||
|
||||
60. **Emoji-as-feature-icon.** Does any feature card, value prop, step number, or pricing tier carry an emoji glyph (✨ 🚀 ⚡ 🔥 🎯 ✅) as its primary icon? If yes, fail. Emoji-as-icon is one of the strongest "AI-default" tells — the model reached for a Unicode glyph instead of choosing an icon library, building a custom mark, or omitting the icon entirely. The fix: pick a single icon library (Lucide / Phosphor / Heroicons — see [assets.md](assets.md)), build a custom SVG, or drop the icon and lead with typography.
|
||||
|
||||
The CSS stamp at Step 6 should record results: `· honest: pass (56) · chrome: pass (57) · tokens: pass (58) · responsive: pass (59) · icons: pass (60)`. Any failure must be fixed before shipping.
|
||||
|
||||
---
|
||||
|
||||
If any answer is **yes**, fix it. Do not ship slop.
|
||||
|
||||
Reference in New Issue
Block a user