Files
hallmark/site/index.html
T
YoussefandClaude Opus 4.7 99e7a065af v0.8 — genres, design.md, lazier loading, two new themes, site rework
Skill:
- Genres (editorial · modern-minimal · atmospheric · playful) as a top-level rule overlay; signal-based detection in Step 1, theme rotation now scoped to the genre's cluster
- `redesign` on a directory or whole project now produces design.md first and locks every page to that system; diversification rule inverts on system-managed projects
- SKILL.md slimmed 532 → ~440 lines: slop-test gates extracted to references/slop-test.md, per-verb sections to references/verbs/, output contract to references/contract.md, with explicit eager / per-build / conditional / end / verb-specific load buckets
- Worked examples (recipes.md, study-examples.md) moved out of skill/references/ into docs/ — no longer auto-loaded
- audit.md gained design.md drift checks (theme drift · macrostructure-family violation · stamp lies · missing system reference)

Site:
- Quiet theme refreshed to ElevenLabs-style polished minimal (Geist, pure white, pill CTAs, two-column hero)
- New Bloom theme — Suno-style atmospheric dark with twin warm radial blooms, Geist display, single warm accent
- Banner additions: sticky Install link, live stamp callout (hover-expands the CSS comment), genre label after the theme name
- T-key onboarding tooltip after 5s idle (localStorage-flagged so it never returns)
- Decision-trail popover on each example tile (600ms hover delay, pure CSS)
- Foundations cut from 8 cards to 5 (Type · Colour · Space · Motion · Voice)
- FAQ section added: 5 typographic Q/A pairs, editorial format, tightened spacing
- Without/With grew from 1 pair to 4 — writing app · dashboard · pricing card · personal site — with a CSS-only tab toggle
- Scroll-jump fix on the W/W tabs: radio inputs no longer position-absolute, so clicking a tab no longer yanks the page back to top
- How-it-works section folded out, content absorbed by FAQ + Install
- 17 themes (was 16); README and skill references updated everywhere

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 21:08:42 +01:00

917 lines
49 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" data-theme="specimen">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="light" />
<title>Hallmark — A design skill that refuses to look AI-generated</title>
<meta name="description"
content="Hallmark is a design skill for AI coding assistants. It encodes the anti-AI-slop consensus — typography, colour, layout, motion, interaction — into one holistic ruleset. Powered by Together AI." />
<meta property="og:title" content="Hallmark — A design skill that refuses to look AI-generated" />
<meta property="og:description"
content="A design skill for AI coding assistants. Encodes the anti-slop consensus into one ruleset. Powered by Together AI." />
<meta property="og:type" content="website" />
<link rel="preload" href="fonts/the-future-regular.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="fonts/the-future-medium.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="fonts/the-future-mono-regular.woff2" as="font" type="font/woff2" crossorigin />
<!-- Google Fonts — Fraunces (Specimen + Studio italic display), Geist (Pastel), Bricolage + Newsreader (Riso). -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,500;12..96,700;12..96,800&family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,500;0,9..144,600;1,9..144,400;1,9..144,500&family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;1,6..72,400;1,6..72,500&display=swap" />
<link rel="stylesheet" href="css/tokens.css" />
<link rel="stylesheet" href="css/base.css" />
<link rel="stylesheet" href="css/components.css" />
<link rel="stylesheet" href="css/sections.css" />
<script>
// Load theme before paint to avoid flash. Order: ?theme= → localStorage → default.
try {
const url = new URL(window.location.href);
const q = url.searchParams.get("theme");
const t = q || localStorage.getItem("hallmark-theme");
if (t) document.documentElement.dataset.theme = t;
} catch (e) { }
</script>
</head>
<body>
<!-- BANNER — sticky top, thin, holds the theme picker -->
<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">v0.8</span>
</a>
<a class="banner__install" href="#install" aria-label="Jump to install section">Install</a>
<span class="banner__stamp" data-stamp aria-label="Current Hallmark stamp">
<span class="banner__stamp-text" data-stamp-text>marquee · specimen · enrich-A</span>
<span class="banner__stamp-detail" data-stamp-detail aria-hidden="true">/* Hallmark · genre: editorial · macrostructure: marquee · theme: specimen · enrichment: A */</span>
</span>
<span class="banner__spacer" aria-hidden="true"></span>
<span class="banner__center" data-theme-current>
<span class="banner__theme">Specimen</span>
<span class="banner__genre" data-theme-genre>editorial</span>
</span>
<div class="banner__picker" role="radiogroup" aria-label="Theme">
<button class="banner__dot" type="button" data-theme-btn="specimen" aria-label="Specimen"
style="--dot: oklch(96% 0.018 80); --dot-edge: oklch(70% 0.04 75);"></button>
<button class="banner__dot" type="button" data-theme-btn="newsprint" aria-label="Newsprint"
style="--dot: oklch(92% 0.045 50); --dot-edge: oklch(32% 0.10 28);"></button>
<button class="banner__dot" type="button" data-theme-btn="atelier" aria-label="Atelier"
style="--dot: oklch(94% 0.005 60); --dot-edge: oklch(45% 0.13 60);"></button>
<button class="banner__dot" type="button" data-theme-btn="garden" aria-label="Garden"
style="--dot: oklch(95% 0.030 130); --dot-edge: oklch(54% 0.16 14);"></button>
<button class="banner__dot" type="button" data-theme-btn="salon" aria-label="Salon"
style="--dot: oklch(94% 0.030 65); --dot-edge: oklch(40% 0.085 50);"></button>
<button class="banner__dot" type="button" data-theme-btn="linen" aria-label="Linen"
style="--dot: oklch(89% 0.022 95); --dot-edge: oklch(46% 0.06 95);"></button>
<button class="banner__dot" type="button" data-theme-btn="almanac" aria-label="Almanac"
style="--dot: oklch(94% 0.008 245); --dot-edge: oklch(38% 0.135 250);"></button>
<button class="banner__dot" type="button" data-theme-btn="midnight" aria-label="Midnight"
style="--dot: oklch(15% 0.022 250); --dot-edge: oklch(72% 0.16 220);"></button>
<button class="banner__dot" type="button" data-theme-btn="terminal" aria-label="Terminal"
style="--dot: oklch(11% 0.018 145); --dot-edge: oklch(78% 0.19 138);"></button>
<button class="banner__dot" type="button" data-theme-btn="brutal" aria-label="Brutal"
style="--dot: oklch(98% 0.001 0); --dot-edge: oklch(60% 0.21 27);"></button>
<button class="banner__dot" type="button" data-theme-btn="manifesto" aria-label="Manifesto"
style="--dot: oklch(10% 0.005 60); --dot-edge: oklch(60% 0.22 27);"></button>
<button class="banner__dot" type="button" data-theme-btn="sport" aria-label="Sport"
style="--dot: oklch(98% 0.003 250); --dot-edge: oklch(58% 0.190 35);"></button>
<button class="banner__dot" type="button" data-theme-btn="studio" aria-label="Studio"
style="--dot: oklch(96.5% 0.014 95); --dot-edge: oklch(46% 0.140 145);"></button>
<button class="banner__dot" type="button" data-theme-btn="pastel" aria-label="Pastel"
style="--dot: oklch(96% 0.022 285); --dot-edge: oklch(56% 0.130 282);"></button>
<button class="banner__dot" type="button" data-theme-btn="riso" aria-label="Riso"
style="--dot: oklch(91% 0.034 30); --dot-edge: oklch(58% 0.170 220);"></button>
<button class="banner__dot" type="button" data-theme-btn="quiet" aria-label="Quiet"
style="--dot: oklch(100% 0 0); --dot-edge: oklch(15% 0 0);"></button>
<button class="banner__dot" type="button" data-theme-btn="bloom" aria-label="Bloom"
style="--dot: oklch(8% 0.012 35); --dot-edge: oklch(72% 0.190 45);"></button>
</div>
<button class="banner__shuffle" type="button" aria-label="Random theme · T cycles · R randomises"
title="Click → random · T cycles · R randomises">
<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M16 3h5v5" />
<path d="M4 20 21 3" />
<path d="M21 16v5h-5" />
<path d="m15 15 6 6" />
<path d="M4 4l5 5" />
</svg>
<span class="banner__shuffle-key">T</span>
</button>
<aside class="t-tooltip" data-t-tooltip hidden role="status" aria-live="polite">
<span class="t-tooltip__arrow" aria-hidden="true"></span>
<span class="t-tooltip__body">
Press <kbd>T</kbd> to see this page in <strong>17 shapes</strong>.
</span>
</aside>
</header>
<main class="page">
<!-- 01 · HERO SLOT — archetype swaps per theme -->
<section class="slot slot--hero reveal" data-slot="hero" id="top" style="--i:0" aria-label="Opening"></section>
<!-- 02 · EXAMPLES — full-bleed rail, the centerpiece -->
<section class="section section--bleed reveal" style="--i:1" id="examples" aria-labelledby="s2">
<header class="section__head">
<p class="section-label">
<span class="num">02</span><span class="divider"></span><span>Examples</span>
</p>
<h2 class="section__title" id="s2">
Eight briefs. Eight different shapes.
</h2>
</header>
<p class="examples__intro">Each page is hand-built HTML and CSS — no shared theme, no shared layout. <span class="examples__hint">Click any card to open the full page →</span></p>
<div class="examples-rail" role="list" aria-label="Eight example landing pages">
<a class="ex-card" href="_tests/01-tide-podcast/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/01-tide.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">01</span>
<span class="ex-card__name">Tide</span>
<span class="ex-card__brief">Indie podcast · warm cream, mono masthead</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Indie podcast for solo hosts.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">editorial</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Letter</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Salon</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">none — typography only</span></p>
</div>
</a>
<a class="ex-card" href="_tests/02-streampipe-cli/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/02-streampipe.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">02</span>
<span class="ex-card__name">Streampipe</span>
<span class="ex-card__brief">Open-source CLI · prose-led docs, embedded terminal</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Open-source CLI tool docs.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">atmospheric</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Long Document</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Terminal</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">Tier-A inline CSS-art terminal</span></p>
</div>
</a>
<a class="ex-card" href="_tests/03-maple-bakery/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/03-maple.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">03</span>
<span class="ex-card__name">Maple Street Bread</span>
<span class="ex-card__brief">Artisan bakery · market-board layout, hand-built SVG</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Artisan bakery, eight breads.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">editorial</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Catalogue</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Almanac</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">Tier-A hand-built SVG silhouettes</span></p>
</div>
</a>
<a class="ex-card" href="_tests/04-meridian-manifesto/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/04-meridian.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">04</span>
<span class="ex-card__name">Meridian</span>
<span class="ex-card__brief">Studio manifesto · dark paper, yellow strike</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Studio manifesto, four principles.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">editorial</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Quote-Led</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Brutal</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">none — voice carries the brand</span></p>
</div>
</a>
<a class="ex-card" href="_tests/05-tracejam-saas/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/05-tracejam.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">05</span>
<span class="ex-card__name">Tracejam</span>
<span class="ex-card__brief">Observability SaaS · dark paper, sticky trace panel</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">SaaS observability platform.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">atmospheric</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Workbench</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Midnight</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">Tier-A sticky trace panel</span></p>
</div>
</a>
<a class="ex-card" href="_tests/06-anya-portfolio/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/06-anya.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">06</span>
<span class="ex-card__name">Anya</span>
<span class="ex-card__brief">Software architect personal site · sticky TOC, pure white</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Software architect personal site.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">modern-minimal</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Index-First</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Quiet</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">none — typography only</span></p>
</div>
</a>
<a class="ex-card" href="_tests/07-foundry-compliance/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/07-foundry.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">07</span>
<span class="ex-card__name">Foundry</span>
<span class="ex-card__brief">SOC2 compliance SaaS · six-tile bento, deep-red accent</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">SOC2 compliance SaaS.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">editorial</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Bento Grid</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Newsprint</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">Tier-A logo grid + counter</span></p>
</div>
</a>
<a class="ex-card" href="_tests/08-cohort-courses/index.html" target="_blank" rel="noopener" role="listitem">
<picture class="ex-card__thumb" aria-hidden="true">
<img src="_tests/_thumbs/08-cohort.png" alt="" loading="lazy" decoding="async" width="1024" height="640" />
</picture>
<div class="ex-card__meta">
<span class="ex-card__num">08</span>
<span class="ex-card__name">Cohort</span>
<span class="ex-card__brief">Cohort-based courses · stat-led, three supporting figures</span>
<span class="ex-card__open">Open ↗</span>
</div>
<div class="ex-card__trail" aria-hidden="true">
<p class="trail__row"><span class="trail__k">Brief</span><span class="trail__v">Cohort-based courses platform.</span></p>
<p class="trail__row"><span class="trail__k">Genre</span><span class="trail__v">editorial</span></p>
<p class="trail__row"><span class="trail__k">Macro</span><span class="trail__v">Stat-Led</span></p>
<p class="trail__row"><span class="trail__k">Theme</span><span class="trail__v">Linen</span></p>
<p class="trail__row"><span class="trail__k">Enrich</span><span class="trail__v">none — typography only</span></p>
</div>
</a>
</div>
</section>
<!-- 03 · WITHOUT / WITH — same copy, two design languages, two examples -->
<section class="section reveal" style="--i:2" aria-labelledby="s3">
<header class="section__head">
<p class="section-label">
<span class="num">03</span><span class="divider"></span><span>Without / with</span>
</p>
<h2 class="section__title" id="s3">
Same brief. Same words. Two very different pages.
</h2>
</header>
<input type="radio" name="vs-toggle" id="vs-notes" class="vs-toggle__input" checked />
<input type="radio" name="vs-toggle" id="vs-dashboard" class="vs-toggle__input" />
<input type="radio" name="vs-toggle" id="vs-pricing" class="vs-toggle__input" />
<input type="radio" name="vs-toggle" id="vs-personal" class="vs-toggle__input" />
<div class="vs-toggle" role="tablist" aria-label="Choose a brief">
<label for="vs-notes" class="vs-toggle__btn" data-vs="notes" role="tab">
<span class="vs-toggle__num">01</span>
<span class="vs-toggle__label">Writing app</span>
</label>
<label for="vs-dashboard" class="vs-toggle__btn" data-vs="dashboard" role="tab">
<span class="vs-toggle__num">02</span>
<span class="vs-toggle__label">Dashboard</span>
</label>
<label for="vs-pricing" class="vs-toggle__btn" data-vs="pricing" role="tab">
<span class="vs-toggle__num">03</span>
<span class="vs-toggle__label">Pricing card</span>
</label>
<label for="vs-personal" class="vs-toggle__btn" data-vs="personal" role="tab">
<span class="vs-toggle__num">04</span>
<span class="vs-toggle__label">Personal site</span>
</label>
</div>
<div class="vs-pairs">
<div class="vs vs--notes" data-vs-pair="notes">
<div class="vs__col">
<div class="vs__head"><span class="vs__label">Without Hallmark</span></div>
<div class="vs__panel" data-variant="slop">
<p class="vs__panel-eyebrow">✨ Introducing</p>
<h3 class="vs__panel-title">Notes that think with you.</h3>
<p class="vs__panel-sub">A writing tool that organizes your ideas as you draft.</p>
<span class="vs__panel-cta">Try free</span>
</div>
<p class="vs__caption">
Centred everything. Purple-to-pink gradient on the headline. Inter top to bottom. A pill button with a gradient fill. A page every LLM has produced ten thousand times.
</p>
</div>
<div class="vs__col">
<div class="vs__head"><span class="vs__label">With Hallmark</span></div>
<div class="vs__panel" data-variant="hallmark">
<p class="vs__panel-eyebrow"><span class="vs__panel-mark" aria-hidden="true"></span>Introducing</p>
<h3 class="vs__panel-title">Notes that think <em>with you.</em></h3>
<p class="vs__panel-sub">A writing tool that organizes your ideas as you draft.</p>
<span class="vs__panel-cta">Try free →</span>
</div>
<p class="vs__caption">
Left-aligned, asymmetric. A display face with character set against a clean body. One small accent on the eyebrow only. A square-edged button. Same words — a page that knows what it is.
</p>
</div>
</div>
<div class="vs vs--dashboard" data-vs-pair="dashboard">
<div class="vs__col">
<div class="vs__head"><span class="vs__label">Without Hallmark</span></div>
<div class="vs__panel vs__panel--dash" data-variant="slop">
<p class="vs__panel-eyebrow">📊 Overview</p>
<h3 class="vs__panel-stat">1,284</h3>
<p class="vs__panel-stat-label">Active sessions today</p>
<span class="vs__panel-badge">↑ 12%</span>
<p class="vs__panel-sub">Up from yesterday. Across 47 regions.</p>
<span class="vs__panel-cta">View report</span>
</div>
<p class="vs__caption">
A glassmorphic widget. Gradient sparkline. Floating green-glow badge. Pill button with gradient fill. Centred on a softly-shadowed card. The AI-default dashboard.
</p>
</div>
<div class="vs__col">
<div class="vs__head"><span class="vs__label">With Hallmark</span></div>
<div class="vs__panel vs__panel--dash" data-variant="hallmark">
<p class="vs__panel-eyebrow"><span class="vs__panel-mark" aria-hidden="true"></span>Overview</p>
<p class="vs__panel-stat-line">
<span class="vs__panel-stat-num">1,284</span>
<span class="vs__panel-stat-delta"><span class="vs__panel-stat-dot" aria-hidden="true"></span>↑ 12%</span>
</p>
<p class="vs__panel-stat-label">Active sessions today.<br />Up from yesterday — across 47 regions.</p>
<span class="vs__panel-cta">View report →</span>
</div>
<p class="vs__caption">
Hairline rule above the figure. Mono tabular numerals at display size. Inline 12% with a single accent dot, no glow. Asymmetric, left-aligned. Square-edge CTA. Information, not decoration.
</p>
</div>
</div>
<div class="vs vs--pricing" data-vs-pair="pricing">
<div class="vs__col">
<div class="vs__head"><span class="vs__label">Without Hallmark</span></div>
<div class="vs__panel vs__panel--pricing" data-variant="slop">
<span class="vs__panel-pop">✨ Most popular</span>
<p class="vs__panel-eyebrow">Starter</p>
<h3 class="vs__panel-price"><span class="vs__panel-price-num">$24</span><span class="vs__panel-price-unit">/month</span></h3>
<p class="vs__panel-sub">For solo writers and side projects.</p>
<ul class="vs__panel-bullets">
<li>✅ 5,000 words / month</li>
<li>✅ Unlimited drafts</li>
<li>✅ Email support</li>
</ul>
<span class="vs__panel-cta">Choose Starter</span>
</div>
<p class="vs__caption">
Glassmorphic centred card. "Most popular" badge with sparkle emoji. Gradient on the price. Emoji checkmarks. Pill button with gradient fill. The B2B SaaS pricing card the LLM ships every time.
</p>
</div>
<div class="vs__col">
<div class="vs__head"><span class="vs__label">With Hallmark</span></div>
<div class="vs__panel vs__panel--pricing" data-variant="hallmark">
<p class="vs__panel-eyebrow"><span class="vs__panel-mark" aria-hidden="true"></span>Recommended</p>
<p class="vs__panel-tier">Starter</p>
<h3 class="vs__panel-price">
<span class="vs__panel-price-num">$24</span>
<span class="vs__panel-price-unit">/ month</span>
</h3>
<p class="vs__panel-sub">For solo writers and side projects.</p>
<ul class="vs__panel-bullets">
<li>5,000 words a month</li>
<li>Unlimited drafts</li>
<li>Reply-by-Wednesday email support</li>
</ul>
<span class="vs__panel-cta">Choose Starter →</span>
</div>
<p class="vs__caption">
Tier name set in display face above a hairline rule. Mono tabular price. No gradients, no glow, no emoji. Plain bullets, plain rules. The price is the design.
</p>
</div>
</div>
<div class="vs vs--personal" data-vs-pair="personal">
<div class="vs__col">
<div class="vs__head"><span class="vs__label">Without Hallmark</span></div>
<div class="vs__panel vs__panel--personal" data-variant="slop">
<span class="vs__panel-avatar" aria-hidden="true">A</span>
<h3 class="vs__panel-name">Anya Reyes</h3>
<p class="vs__panel-sub">Software architect &amp; distributed-systems builder.</p>
<div class="vs__panel-pills">
<span class="vs__panel-pill">About</span>
<span class="vs__panel-pill">Work</span>
<span class="vs__panel-pill">Contact</span>
</div>
</div>
<p class="vs__caption">
Centred avatar bubble. Gradient on the name. Three pill nav buttons in a row. Inter top to bottom. The portfolio template the LLM falls back to when it doesn't know who you are.
</p>
</div>
<div class="vs__col">
<div class="vs__head"><span class="vs__label">With Hallmark</span></div>
<div class="vs__panel vs__panel--personal" data-variant="hallmark">
<p class="vs__panel-eyebrow"><span class="vs__panel-mark" aria-hidden="true"></span>About · 01</p>
<h3 class="vs__panel-name">Anya <em>Reyes.</em></h3>
<p class="vs__panel-bio">Software architect, ten years on distributed systems. Currently building Streampipe. Writes about latency and the small print of caches.</p>
<p class="vs__panel-links"><a href="#" class="vs__panel-linkitem">Notes</a> · <a href="#" class="vs__panel-linkitem">Work</a> · <a href="#" class="vs__panel-linkitem">Garden</a> · <a href="#" class="vs__panel-linkitem">Contact</a></p>
</div>
<p class="vs__caption">
No avatar. Italic name with a roman emphasis on the surname. Numbered eyebrow (<code>01</code>) like a chapter mark. Body serif bio that reads like a letter. Plain text links separated by middots. A page that knows its subject.
</p>
</div>
</div>
</div>
</section>
<!-- 04 · FOUNDATIONS — five plain-English rules -->
<section class="section reveal" style="--i:3" aria-labelledby="s4">
<header class="section__head">
<p class="section-label">
<span class="num">04</span><span class="divider"></span><span>Foundations</span>
</p>
<h2 class="section__title" id="s4">
Five things Hallmark holds the line on — explained without the jargon.
</h2>
</header>
<div class="foundations">
<article class="spec spec--feature">
<header class="spec__head">
<span class="spec__name">Type</span>
<span class="spec__num">F / 01</span>
</header>
<p class="spec__rule">Pick fonts on purpose. Skip Inter and Geist — the defaults every site uses. Pair a display face that has a personality with a clean body face, and lean into the extreme weights, light or heavy, not the safe middle.</p>
<div class="spec__body">
<div class="spec__viz spec__viz--type">
<div class="spec__viz-row spec__viz-row--display"><span>Hallmark</span><em class="spec__viz-tag">Fraunces · 900 italic</em></div>
<div class="spec__viz-row spec__viz-row--body"><span>Hallmark</span><em class="spec__viz-tag">Geist · 300</em></div>
<div class="spec__viz-row spec__viz-row--mono"><span>Hallmark</span><em class="spec__viz-tag">Mono · 500</em></div>
</div>
</div>
</article>
<article class="spec spec--feature">
<header class="spec__head">
<span class="spec__name">Colour</span>
<span class="spec__num">F / 02</span>
</header>
<p class="spec__rule">One accent colour, used so sparingly you almost miss it — less than 3% of what's on screen. Skip pure black and pure white (they're harsher than they look). Avoid purple gradients.</p>
<div class="spec__body">
<div class="spec__viz spec__viz--colour" aria-hidden="true">
<span class="spec__viz-dot"></span>
<p class="spec__viz-caption">One accent. The whole field is paper. The dot is the accent.</p>
</div>
<div class="swatch-row spec__viz-swatches">
<div class="swatch swatch--light" style="background: var(--color-paper);">Paper</div>
<div class="swatch swatch--light" style="background: var(--color-paper-3);">Rule</div>
<div class="swatch" style="background: var(--color-neutral);">Mute</div>
<div class="swatch" style="background: var(--color-ink);">Ink</div>
<div class="swatch" style="background: var(--color-accent);">Accent</div>
</div>
</div>
</article>
<article class="spec">
<header class="spec__head">
<span class="spec__name">Space</span>
<span class="spec__num">F / 03</span>
</header>
<p class="spec__rule">Generous space, used unevenly. Pick one consistent scale so things feel related. Asymmetry on purpose, never by accident — centred-everything is a tell.</p>
<div class="spec__body">
<div class="spec__viz spec__viz--space" aria-hidden="true">
<div class="spec__viz-grid spec__viz-grid--bad">
<span class="vg-bar vg-bar--xl"></span>
<span class="vg-bar vg-bar--md"></span>
<span class="vg-bar vg-bar--sm"></span>
</div>
<div class="spec__viz-grid spec__viz-grid--good">
<span class="vg-bar vg-bar--xl"></span>
<span class="vg-bar vg-bar--md"></span>
<span class="vg-bar vg-bar--sm"></span>
</div>
</div>
<p class="spec__viz-pair"><span>Centred (a tell)</span><span>Asymmetric (designed)</span></p>
</div>
</article>
<article class="spec">
<header class="spec__head">
<span class="spec__name">Motion</span>
<span class="spec__num">F / 04</span>
</header>
<p class="spec__rule">Keep motion quiet. One smooth entrance feels designed; ten little bounces feel busy. Animate fade and slide — never size, colour, or layout.</p>
<div class="spec__body">
<div class="spec__viz spec__viz--motion">
<button class="spec__viz-play" type="button" data-motion-demo aria-label="Play motion demo">
<span class="spec__viz-play-icon" aria-hidden="true"></span>
Play
</button>
<div class="spec__viz-stage" aria-hidden="true">
<span class="spec__viz-block" data-motion-block></span>
</div>
</div>
</div>
</article>
<article class="spec spec--strip">
<header class="spec__head">
<span class="spec__name">Voice</span>
<span class="spec__num">F / 05</span>
</header>
<p class="spec__rule">Write like a person. Specific verbs over vague ones. Link text that makes sense out of context. Real apostrophes, not straight quotes. No "seamless," no "unleash," no "built for the modern team."</p>
<div class="spec__body">
<div class="spec__viz spec__viz--copy">
<div class="spec__viz-copy-col" data-variant="bad">
<p class="spec__viz-copy-label">Vague</p>
<p class="spec__viz-copy-line">Click here</p>
<p class="spec__viz-copy-line">Get started</p>
<p class="spec__viz-copy-line">Built for the modern team</p>
<p class="spec__viz-copy-line">Unleash the future</p>
</div>
<div class="spec__viz-copy-col" data-variant="good">
<p class="spec__viz-copy-label">Specific</p>
<p class="spec__viz-copy-line">View pricing plans</p>
<p class="spec__viz-copy-line">Save changes</p>
<p class="spec__viz-copy-line">The email API for developers</p>
<p class="spec__viz-copy-line">Notes that think with you</p>
</div>
</div>
</div>
</article>
</div>
</section>
<!-- 05 · FAQ — six typographic Q/A pairs -->
<section class="section reveal" style="--i:4" id="faq" aria-labelledby="s5">
<header class="section__head">
<p class="section-label">
<span class="num">05</span><span class="divider"></span><span>FAQ</span>
</p>
<h2 class="section__title" id="s5">
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>
<!-- 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>Install</span>
</p>
<h2 class="section__title" id="s6">
One command. Works in every harness.
</h2>
</header>
<div class="install-pane">
<div class="install-pane__row install-pane__row--cmd">
<p class="install-pane__label"><span class="install-pane__step">I</span> Run</p>
<div class="install-pane__cmd" data-copy-source>
<span class="install-pane__prompt" aria-hidden="true">$</span>
<span class="install-pane__cmd-text" data-copy-text>npx skills add hallmark</span>
<button class="install-pane__copy" type="button" data-copy-btn aria-label="Copy install command">
<span class="install-pane__copy-default">Copy</span>
<span class="install-pane__copy-done">Copied</span>
</button>
</div>
</div>
<div class="install-pane__row">
<p class="install-pane__label"><span class="install-pane__step">II</span> In</p>
<ul class="install-pane__harnesses">
<li class="harness">
<span class="harness__name">Claude Code</span>
<code class="harness__path">~/.claude/skills/hallmark/</code>
<span class="harness__status harness__status--ok">auto-detected</span>
</li>
<li class="harness">
<span class="harness__name">Cursor</span>
<code class="harness__path">.cursor/rules/hallmark.mdc</code>
<span class="harness__status harness__status--ok">auto-detected</span>
</li>
<li class="harness">
<span class="harness__name">Codex &amp; others</span>
<code class="harness__path">git clone · copy skill/</code>
<span class="harness__status">manual</span>
</li>
</ul>
</div>
<div class="install-pane__row">
<p class="install-pane__label"><span class="install-pane__step">III</span> Then</p>
<p class="install-pane__next">Ask your agent for a UI. <code>hallmark</code> attaches itself when the prompt mentions design, audit, refine, redesign, or study — so the rules apply without you naming them.</p>
</div>
</div>
</section>
<!-- FOOTER SLOT — archetype swaps per theme -->
<footer class="slot slot--foot reveal" data-slot="footer" style="--i:6" role="contentinfo" aria-label="Colophon">
</footer>
</main>
<!-- ─── Easter egg ─── revealed when the user spams T —— -->
<aside class="easter" data-easter-egg hidden role="dialog" aria-modal="true" aria-label="A note from Hallmark">
<div class="easter__panel">
<ol class="easter__lines" aria-live="polite">
<li class="easter__line easter__line--cmd"><span class="easter__prompt">$</span> hallmark observe</li>
<li class="easter__line">
<span class="easter__arrow">&gt;</span>
<span class="easter__num" data-easter-cycles>1.0</span>× in
<span class="easter__num" data-easter-seconds>3.2</span>s.
</li>
<li class="easter__line easter__line--punchline" data-easter-punchline>
<span class="easter__arrow">&gt;</span> <span data-easter-line>chill, designer.</span><span class="easter__cursor" aria-hidden="true"></span>
</li>
</ol>
<p class="easter__hint">
<span>returning to the page in a moment</span>
</p>
</div>
</aside>
<!-- ─────────── HERO ARCHETYPES ─────────── -->
<template id="hero-marquee">
<div class="hero hero--marquee">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<h1 class="hero__display" data-text="{{title}}">{{title}}</h1>
<p class="hero__lede">{{lede}}</p>
<div class="hero__cta">
<p class="label">{{ctaLabel}}</p>
<pre class="code"
data-copy-source><span class="prompt">$</span><span data-copy-text>npx skills add hallmark</span><button class="code__copy" type="button" data-copy-btn aria-label="Copy install command"><span class="code__copy-default">Copy</span><span class="code__copy-done">Copied</span></button></pre>
</div>
</div>
</template>
<template id="hero-split">
<div class="hero hero--split">
<div class="hero__col">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<h1 class="hero__display">{{title}}</h1>
<p class="hero__lede">{{lede}}</p>
</div>
<aside class="hero__proof">
<p class="label">{{proofLabel}}</p>
<p class="hero__proof-line">{{proofA}}</p>
<p class="hero__proof-line">{{proofB}}</p>
<p class="hero__proof-line">{{proofC}}</p>
<a href="#install" class="link">{{cta}} &rarr;</a>
</aside>
</div>
</template>
<template id="hero-stat-led">
<div class="hero hero--stat">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<span class="hero__stat tabular-nums">{{stat}}</span>
<p class="hero__qualifier">{{qualifier}}</p>
<p class="hero__lede">{{lede}}</p>
<a href="#install" class="link hero__link">{{cta}} &rarr;</a>
</div>
</template>
<template id="hero-quote-led">
<div class="hero hero--quote">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<blockquote class="hero__quote">
<p>&ldquo;{{quote}}&rdquo;</p>
<footer class="hero__attrib">— {{attrib}}</footer>
</blockquote>
<p class="hero__lede">{{lede}}</p>
<a href="#install" class="link hero__link">{{cta}} &rarr;</a>
</div>
</template>
<template id="hero-letter">
<div class="hero hero--letter">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<p class="hero__salutation">{{salutation}}</p>
<p class="hero__letter-body">{{letterBody}}</p>
<p class="hero__signoff">{{signoff}}<br><span class="hero__sign">— Hallmark</span></p>
</div>
</template>
<template id="hero-photographic">
<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>
</div>
<span class="hero__photo-caption">{{captionA}} · {{captionB}}</span>
</div>
<div class="hero__photo-text">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<h1 class="hero__display hero__display--small">{{title}}</h1>
<p class="hero__lede">{{lede}}</p>
</div>
</div>
</template>
<template id="hero-clipped">
<div class="hero hero--clipped">
<div class="hero__copy">
<p class="hero__eyebrow"><span class="mark" aria-hidden="true"></span>{{eyebrow}}</p>
<h1 class="hero__display hero__display--small">{{title}}</h1>
<p class="hero__lede">{{lede}}</p>
<div class="hero__cta">
<pre class="code"
data-copy-source><span class="prompt">$</span><span data-copy-text>npx skills add hallmark</span><button class="code__copy" type="button" data-copy-btn aria-label="Copy install command"><span class="code__copy-default">Copy</span><span class="code__copy-done">Copied</span></button></pre>
</div>
</div>
<figure class="hero__mock" aria-hidden="true">
<header class="hero__mock-chrome">
<span class="hero__mock-dot"></span>
<span class="hero__mock-dot"></span>
<span class="hero__mock-dot"></span>
<span class="hero__mock-url">hallmark.studio</span>
</header>
<div class="hero__mock-body">
<aside class="hero__mock-rail">
<span class="hero__mock-rail-item is-active"></span>
<span class="hero__mock-rail-item"></span>
<span class="hero__mock-rail-item"></span>
<span class="hero__mock-rail-item"></span>
<span class="hero__mock-rail-item"></span>
</aside>
<main class="hero__mock-main">
<div class="hero__mock-row hero__mock-row--head">
<span class="hero__mock-bar hero__mock-bar--lg"></span>
<span class="hero__mock-pill"></span>
</div>
<div class="hero__mock-grid">
<div class="hero__mock-card hero__mock-card--accent">
<span class="hero__mock-bar hero__mock-bar--xs"></span>
<span class="hero__mock-stat">{{mockStat}}</span>
<span class="hero__mock-bar hero__mock-bar--sm"></span>
</div>
<div class="hero__mock-card">
<span class="hero__mock-bar hero__mock-bar--xs"></span>
<span class="hero__mock-spark" aria-hidden="true"></span>
</div>
<div class="hero__mock-card hero__mock-card--wide">
<span class="hero__mock-bar hero__mock-bar--xs"></span>
<div class="hero__mock-rows">
<span class="hero__mock-bar"></span>
<span class="hero__mock-bar"></span>
<span class="hero__mock-bar hero__mock-bar--short"></span>
</div>
</div>
</div>
</main>
</div>
</figure>
</div>
</template>
<!-- ─────────── FOOTER ARCHETYPES ─────────── -->
<template id="footer-masthead">
<div class="foot foot--masthead">
<span class="foot__wordmark">Hallmark</span>
<p class="foot__tagline">{{tagline}}</p>
<div class="foot__links">
<a href="https://github.com/Luffixos/hallmark" class="link">GitHub</a>
</div>
<p class="foot__powered"><span class="foot__powered-mark">Powered by Together AI</span></p>
</div>
</template>
<template id="footer-inline">
<div class="foot foot--inline">
<span class="foot__wordmark-small">Hallmark</span>
<span class="foot__sep" aria-hidden="true"></span>
<span class="foot__line">{{tagline}}</span>
<span class="foot__sep" aria-hidden="true"></span>
<a href="https://github.com/Luffixos/hallmark" class="link">GitHub</a>
<span class="foot__sep" aria-hidden="true"></span>
<span class="foot__powered-mark">Powered by Together AI</span>
</div>
</template>
<template id="footer-index">
<div class="foot foot--index">
<div class="foot__col">
<p class="foot__col-head">Skill</p>
<ul>
<li><a href="https://github.com/Luffixos/hallmark" class="link">GitHub</a></li>
<li><a href="#install" class="link">Install</a></li>
<li><a href="#examples" class="link">Examples</a></li>
</ul>
</div>
<div class="foot__col">
<p class="foot__col-head">Catalog</p>
<ul>
<li>17 themes</li>
<li>21 macrostructures</li>
<li>32 archetypes</li>
<li>38 slop-test gates</li>
</ul>
</div>
<div class="foot__col">
<p class="foot__col-head">Powered</p>
<ul>
<li><span class="foot__powered-mark">Together AI</span></li>
<li>MIT licensed</li>
<li>v0.7.0</li>
</ul>
</div>
</div>
</template>
<template id="footer-dense">
<pre class="foot foot--dense">{{denseColophon}}</pre>
</template>
<script type="module" src="js/main.js"></script>
</body>
</html>