Add 5 themes (Coral · Violet · Aurora · Halo · Plume) → 22 themes total · study tiles use <img>

Themes:
- Coral (modern-minimal) — warm-grey paper, single coral accent, Geist + General Sans pair, pill CTAs. The "Stripe-not-Linear" register.
- Violet (modern-minimal) — near-white + near-black, single quiet violet accent, tight Geist. The Linear voice without copying it.
- Aurora (atmospheric) — dark cool canvas with two cool blooms (cyan top-right, teal-green bottom-left), Sentient body, single cyan accent. The dev-tool-after-dark register.
- Halo (atmospheric) — neutral charcoal canvas with a single warm-amber bloom positioned ONLY around the hero (fixed-attached pseudo-element clipped to top 80vh). Below the hero the page is content-led — less Suno, more "tool you actually work in."
- Plume (playful) — warm cream paper with alternating tinted bands on sections, soft rose accent, hover-lift on cards, friendly motion. Closer to actual playful than Pastel's post-Linear-soft.

Catalog totals: editorial 12 · modern-minimal 3 · atmospheric 5 · playful 2 = 22 themes. Banner picker, THEMES, ARCHETYPES, COPY, and THEME_GENRES maps all updated. README cluster list reorganised by genre.

Study gallery:
- Replaced <video> with <img> in all 4 cards (videos deferred until production-ready). Existing test-page thumbnails serve as the visual; tiles 03 and 04 keep the data-user-content placeholder + DNA scaffold for the user to fill later.
- CSS .study-card__video class kept alongside new .study-card__img selector so the future video swap is one-line.

Theme-count refs (17 → 22) updated across SKILL.md, README, index.html, main.js, T-tooltip, easter-egg punchlines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Youssef
2026-05-01 23:01:00 +01:00
co-authored by Claude Opus 4.7
parent 4b76eb0e3c
commit e63e28b782
5 changed files with 612 additions and 28 deletions
+5 -5
View File
@@ -2,8 +2,8 @@
**A design skill that studies what you admire — and rebuilds your content with it.**
→ Live demo: **[hallmark-murex.vercel.app](https://hallmark-murex.vercel.app)** · seventeen themes, eight worked tests, press `T` to cycle.
→ Current version: **v0.8.0** — adds genres (editorial · modern-minimal · atmospheric · playful), `design.md` for whole-project redesigns, lazy reference loading, and two new themes (Quiet refreshed, Bloom added).
→ Live demo: **[hallmark-murex.vercel.app](https://hallmark-murex.vercel.app)** · twenty-two themes, eight worked tests, press `T` to cycle.
→ Current version: **v0.8.0** — adds genres (editorial · modern-minimal · atmospheric · playful), `design.md` for whole-project redesigns, lazy reference loading, the 2+1 font rule with 45-gate slop test, component-library exports (tokens.css always emitted; Tailwind / DTCG / shadcn formats inline in design.md), a Study gallery on the marketing site, and seven new themes (Quiet refreshed, plus Bloom, Coral, Violet, Aurora, Halo, Plume).
<table>
<tr>
@@ -97,10 +97,10 @@ Each page is its own self-contained HTML + CSS — no shared theme, no shared la
## What's inside
- **[`SKILL.md`](skill/SKILL.md)** — the routing file. Six-step design flow (including `Step 2.5 · Check project memory` reading `.hallmark/log.json`), 38-question slop test, output contract.
- **[`references/`](skill/references/)** — short, opinionated rule files: typography, colour, layout, motion, microinteractions, interaction-and-states, responsive, copy, anti-patterns, the 21 named macrostructures, the 36 component archetypes with variation knobs, the 6 primitive structure axes, the vision-extraction protocol for `study`, hero enrichment, custom-craft (CSS art over Lottie), assets, the slop-test gates, four genre rule-overlays, and per-verb dispatchers.
- **[`SKILL.md`](skill/SKILL.md)** — the routing file. Six-step design flow (including `Step 2.5 · Check project memory` reading `.hallmark/log.json`), 45-gate slop test, output contract, always-on `tokens.css` export.
- **[`references/`](skill/references/)** — short, opinionated rule files: typography, colour, layout, motion, microinteractions, interaction-and-states (with the input-state checklist), responsive, copy, anti-patterns, the 21 named macrostructures, the 36 component archetypes with variation knobs, the 6 primitive structure axes, the vision-extraction protocol for `study`, hero enrichment, custom-craft (CSS art over Lottie), assets, the slop-test gates, four genre rule-overlays, per-verb dispatchers, and the export-formats reference (Tailwind / DTCG / shadcn / tokens.css).
- **[`docs/`](docs/)** — human-reading content: **[`recipes.md`](docs/recipes.md)** (8 worked briefs + a canonical try-it prompt) and **[`study-examples.md`](docs/study-examples.md)** (3 worked DNA-extractions). Not auto-loaded by the skill.
- **[`site/`](site/)** — a self-demonstrating landing page. Hand-written HTML + CSS + ES module, no framework, no build step. **Seventeen themes** balanced across the warm / cool / neutral / dark spectrum: warm-paper (Specimen, Atelier, Newsprint, Salon, Riso), cool-paper (Linen-cool-slate, Studio-cool-grey, Garden, Almanac, Pastel, Sport), polished-minimal (Quiet), neutral (Brutal), dark (Midnight, Terminal, Manifesto, Bloom). Switching themes literally rebuilds the page — different hero archetype, different footer archetype.
- **[`site/`](site/)** — a self-demonstrating landing page. Hand-written HTML + CSS + ES module, no framework, no build step. **Twenty-two themes** clustered into four genres: **editorial** (Specimen, Atelier, Newsprint, Salon, Linen, Almanac, Garden, Studio, Sport, Riso, Brutal, Manifesto), **modern-minimal** (Quiet, Coral, Violet), **atmospheric** (Midnight, Terminal, Bloom, Aurora, Halo), **playful** (Pastel, Plume). Switching themes literally rebuilds the page — different hero archetype, different footer archetype.
---
+262
View File
@@ -2894,6 +2894,267 @@ html[data-theme="bloom"] body {
animation-delay: calc(var(--i, 0) * 70ms);
}
/* ───────────── CORAL — modern-minimal · Stripe-not-Linear ─────────────
Inherits the Quiet "polished minimal" structure but with a warm-grey
paper and a coral accent on focus rings + small marks. */
[data-theme="coral"] .reveal,
[data-theme="coral"] .reveal.is-in,
[data-theme="coral"] .slot[data-populating] > * {
opacity: 1;
transform: none;
animation: none;
}
[data-theme="coral"] .hero__display,
[data-theme="coral"] .hero__quote p,
[data-theme="coral"] .hero__stat,
[data-theme="coral"] .section__title,
[data-theme="coral"] .foot__wordmark,
[data-theme="coral"] .spec__name,
[data-theme="coral"] .ex-card__name,
[data-theme="coral"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
letter-spacing: -0.025em;
}
[data-theme="coral"] .install-pane__copy {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
border-radius: 999px;
}
/* ───────────── VIOLET — modern-minimal · Linear voice ─────────────
Tighter typographic feel than Coral. Near-white paper, near-black
ink, single quiet violet accent on focus + small marks. */
[data-theme="violet"] .reveal,
[data-theme="violet"] .reveal.is-in,
[data-theme="violet"] .slot[data-populating] > * {
opacity: 1;
transform: none;
animation: none;
}
[data-theme="violet"] .hero__display,
[data-theme="violet"] .hero__quote p,
[data-theme="violet"] .hero__stat,
[data-theme="violet"] .section__title,
[data-theme="violet"] .foot__wordmark,
[data-theme="violet"] .spec__name,
[data-theme="violet"] .ex-card__name,
[data-theme="violet"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
letter-spacing: -0.035em;
}
[data-theme="violet"] .install-pane__copy {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
border-radius: 999px;
}
/* ───────────── AURORA — atmospheric · cool blue-green dark ─────────────
Two cool blooms behind the content (cyan top-right, teal-green
bottom-left). Sentient body for warmth. */
html[data-theme="aurora"] {
background: var(--color-paper);
}
html[data-theme="aurora"] body {
background:
radial-gradient(ellipse 75% 55% at 92% 0%,
color-mix(in oklch, var(--color-accent) 28%, transparent) 0%,
transparent 55%),
radial-gradient(ellipse 70% 60% at 5% 100%,
color-mix(in oklch, var(--color-accent-2) 30%, transparent) 0%,
transparent 60%),
var(--color-paper);
background-attachment: fixed;
min-height: 100dvh;
}
[data-theme="aurora"] .hero__display,
[data-theme="aurora"] .hero__quote p,
[data-theme="aurora"] .hero__stat,
[data-theme="aurora"] .section__title,
[data-theme="aurora"] .foot__wordmark,
[data-theme="aurora"] .spec__name,
[data-theme="aurora"] .ex-card__name,
[data-theme="aurora"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
letter-spacing: -0.03em;
}
[data-theme="aurora"] .hero__lede,
[data-theme="aurora"] .install-pane__next,
[data-theme="aurora"] .ex-card__brief {
font-family: var(--font-body);
font-style: normal;
color: var(--color-ink-2);
}
[data-theme="aurora"] .banner {
background: color-mix(in oklch, var(--color-paper) 68%, transparent);
border-block-end-color: var(--color-rule);
}
[data-theme="aurora"] .reveal { transform: none; }
[data-theme="aurora"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.2) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 70ms);
}
[data-theme="aurora"] .ex-card,
[data-theme="aurora"] .install-pane,
[data-theme="aurora"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper-2);
}
[data-theme="aurora"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
border-radius: 999px;
}
/* ───────────── HALO — atmospheric · hero-only amber bloom ─────────────
The bloom is a single moment near the top. Below the hero the page
is content-led on charcoal — less Suno, more "tool you actually
work in." Implemented as a fixed-position pseudo-element clipped
to the top ~80vh. */
html[data-theme="halo"] {
background: var(--color-paper);
}
html[data-theme="halo"] body {
position: relative;
background: var(--color-paper);
min-height: 100dvh;
}
html[data-theme="halo"] body::before {
content: "";
position: fixed;
inset: 0 0 auto 0;
height: 80vh;
pointer-events: none;
z-index: 0;
background:
radial-gradient(ellipse 60% 80% at 70% 0%,
color-mix(in oklch, var(--color-accent) 22%, transparent) 0%,
transparent 60%);
opacity: 1;
}
html[data-theme="halo"] .banner,
html[data-theme="halo"] main,
html[data-theme="halo"] .easter,
html[data-theme="halo"] aside {
position: relative;
z-index: 1;
}
[data-theme="halo"] .hero__display,
[data-theme="halo"] .hero__quote p,
[data-theme="halo"] .hero__stat,
[data-theme="halo"] .section__title,
[data-theme="halo"] .foot__wordmark,
[data-theme="halo"] .spec__name,
[data-theme="halo"] .ex-card__name,
[data-theme="halo"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
letter-spacing: -0.025em;
}
[data-theme="halo"] .banner {
background: color-mix(in oklch, var(--color-paper) 72%, transparent);
border-block-end-color: var(--color-rule);
}
[data-theme="halo"] .ex-card,
[data-theme="halo"] .install-pane,
[data-theme="halo"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper-2);
}
[data-theme="halo"] .reveal { transform: none; }
[data-theme="halo"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.1) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 60ms);
}
/* ───────────── PLUME — playful · warm cream + tinted bands ─────────────
Alternating section backgrounds (paper vs paper-2), hover-lift on
cards, soft drop shadows, friendly motion. Closer to actual playful
than Pastel's post-Linear-soft. */
[data-theme="plume"] .page > .section:nth-child(even) {
background: var(--color-paper-2);
margin-inline: calc(-1 * var(--page-gutter));
padding-inline: var(--page-gutter);
padding-block: var(--space-2xl);
border-radius: 0;
}
[data-theme="plume"] .hero__display,
[data-theme="plume"] .hero__quote p,
[data-theme="plume"] .hero__stat,
[data-theme="plume"] .section__title,
[data-theme="plume"] .foot__wordmark,
[data-theme="plume"] .spec__name,
[data-theme="plume"] .ex-card__name,
[data-theme="plume"] .harness__name {
font-family: var(--font-display);
font-weight: 700;
letter-spacing: -0.025em;
}
[data-theme="plume"] .hero__lede,
[data-theme="plume"] .ex-card__brief,
[data-theme="plume"] .install-pane__next,
[data-theme="plume"] .spec__rule,
[data-theme="plume"] .foot__tagline {
font-family: var(--font-body);
font-style: normal;
}
[data-theme="plume"] .ex-card,
[data-theme="plume"] .install-pane,
[data-theme="plume"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper);
border-color: var(--color-rule-2);
}
@media (hover: hover) and (pointer: fine) {
[data-theme="plume"] .ex-card {
transition: transform 200ms var(--ease-out),
box-shadow 200ms var(--ease-out),
border-color 120ms var(--ease-out);
}
[data-theme="plume"] .ex-card:hover {
transform: translateY(-3px);
box-shadow: 0 14px 32px -14px oklch(45% 0.10 18 / 0.22);
}
}
[data-theme="plume"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
border-radius: 999px;
}
/* ───────────── EXAMPLES RAIL — TILES ─────────────
Each tile in the horizontal scroll-snap rail. Cards inherit the
active theme's --radius-card, --rule-card, and --shadow-card so
@@ -3063,6 +3324,7 @@ html[data-theme="bloom"] body {
overflow: hidden;
}
.study-card__img,
.study-card__video {
display: block;
width: 100%;
+202
View File
@@ -865,6 +865,198 @@
--section-head-gap: 2rem;
}
/* ──────────────────────────────────────────────────────────────
CORAL — modern-minimal · warm-grey paper · single coral accent
The "Stripe-not-Linear" register. Geist + General Sans. Pill CTAs,
warm greys instead of pure neutral. The accent is restrained — a
coral mark, not a flood.
────────────────────────────────────────────────────────────── */
[data-theme="coral"] {
--color-paper: oklch(96.5% 0.005 50);
--color-paper-2: oklch(94% 0.006 50);
--color-paper-3: oklch(91% 0.008 50);
--color-rule: oklch(86% 0.008 50);
--color-rule-2: oklch(72% 0.010 50);
--color-muted: oklch(52% 0.012 50);
--color-neutral: oklch(38% 0.012 45);
--color-ink-2: oklch(28% 0.012 40);
--color-ink: oklch(20% 0.010 35);
--color-accent: oklch(64% 0.165 28); /* warm coral */
--color-accent-ink: oklch(98% 0.005 50);
--color-focus: oklch(64% 0.165 28);
--font-display: "Geist", "General Sans", ui-sans-serif, system-ui, sans-serif;
--font-body: "Geist", "General Sans", ui-sans-serif, system-ui, sans-serif;
--font-serif: ui-serif, Georgia, serif;
--font-label: "Geist Mono", ui-monospace, monospace;
--font-mono: "Geist Mono", ui-monospace, monospace;
--display-weight: 600;
--display-style: normal;
--text-display: clamp(2.5rem, 5vw + 0.5rem, 4.5rem);
--text-display-s: clamp(2rem, 3vw + 0.5rem, 3rem);
--tracking-display: -0.025em;
--tracking-tight: -0.015em;
--tracking-label: 0.05em;
}
/* ──────────────────────────────────────────────────────────────
VIOLET — modern-minimal · near-white + near-black · quiet violet
The Linear voice without copying it. Tight Geist, restrained ink,
one quiet violet accent on focus + small marks.
────────────────────────────────────────────────────────────── */
[data-theme="violet"] {
--color-paper: oklch(99% 0.003 280);
--color-paper-2: oklch(97% 0.004 280);
--color-paper-3: oklch(94% 0.005 280);
--color-rule: oklch(90% 0.006 280);
--color-rule-2: oklch(78% 0.008 280);
--color-muted: oklch(50% 0.012 280);
--color-neutral: oklch(36% 0.014 280);
--color-ink-2: oklch(28% 0.018 280);
--color-ink: oklch(14% 0.015 280);
--color-accent: oklch(58% 0.16 285); /* quiet violet */
--color-accent-ink: oklch(99% 0.003 280);
--color-focus: oklch(58% 0.16 285);
--font-display: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-body: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-serif: ui-serif, Georgia, serif;
--font-label: "Geist Mono", ui-monospace, monospace;
--font-mono: "Geist Mono", ui-monospace, monospace;
--display-weight: 600;
--display-style: normal;
--text-display: clamp(2.5rem, 5.5vw + 0.5rem, 5rem);
--text-display-s: clamp(2rem, 3vw + 0.5rem, 3rem);
--tracking-display: -0.035em;
--tracking-tight: -0.02em;
--tracking-label: 0.04em;
}
/* ──────────────────────────────────────────────────────────────
AURORA — atmospheric · cool blue-green gradient on near-black
The Linear/Vercel-after-dark register. Sentient body, single cyan
accent, two cool blooms behind the content (cyan + teal-green).
────────────────────────────────────────────────────────────── */
[data-theme="aurora"] {
--color-paper: oklch(11% 0.025 200); /* dark cool, cyan tilt */
--color-paper-2: oklch(15% 0.028 200);
--color-paper-3: oklch(18% 0.030 200);
--color-rule: oklch(28% 0.022 200);
--color-rule-2: oklch(38% 0.024 200);
--color-muted: oklch(60% 0.018 200);
--color-neutral: oklch(74% 0.014 200);
--color-ink-2: oklch(82% 0.012 200);
--color-ink: oklch(96% 0.010 200);
--color-accent: oklch(72% 0.170 200); /* cyan */
--color-accent-ink: oklch(11% 0.025 200);
--color-accent-2: oklch(64% 0.150 175); /* secondary teal-green */
--color-focus: oklch(72% 0.170 200);
--font-display: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-body: "Sentient", "Geist", ui-sans-serif, system-ui, sans-serif;
--font-serif: "Sentient", ui-serif, Georgia, serif;
--font-label: "Geist Mono", ui-monospace, monospace;
--font-mono: "Geist Mono", ui-monospace, monospace;
--display-weight: 600;
--display-style: normal;
--text-display: clamp(3rem, 6vw + 1rem, 5.75rem);
--text-display-s: clamp(2rem, 3vw + 1rem, 3.5rem);
--tracking-display: -0.035em;
--tracking-tight: -0.02em;
--tracking-label: 0.10em;
--lh-tight: 1.05;
--lh-snug: 1.18;
}
/* ──────────────────────────────────────────────────────────────
HALO — atmospheric · neutral charcoal canvas · warm-amber bloom
only around the hero. Less Suno, more "tool you actually work in."
The bloom is a single moment near the top; the rest of the page
is content-led on charcoal.
────────────────────────────────────────────────────────────── */
[data-theme="halo"] {
--color-paper: oklch(13% 0.005 60); /* neutral charcoal, hint warm */
--color-paper-2: oklch(17% 0.006 60);
--color-paper-3: oklch(22% 0.008 60);
--color-rule: oklch(28% 0.008 60);
--color-rule-2: oklch(38% 0.010 60);
--color-muted: oklch(58% 0.010 60);
--color-neutral: oklch(72% 0.010 60);
--color-ink-2: oklch(80% 0.008 60);
--color-ink: oklch(94% 0.005 60);
--color-accent: oklch(74% 0.16 70); /* warm amber */
--color-accent-ink: oklch(13% 0.005 60);
--color-focus: oklch(74% 0.16 70);
--font-display: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-body: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-serif: "Instrument Serif", ui-serif, Georgia, serif;
--font-label: "Geist Mono", ui-monospace, monospace;
--font-mono: "Geist Mono", ui-monospace, monospace;
--display-weight: 600;
--display-style: normal;
--text-display: clamp(2.75rem, 5vw + 1rem, 5rem);
--text-display-s: clamp(2rem, 3vw + 0.5rem, 3rem);
--tracking-display: -0.03em;
--tracking-tight: -0.018em;
--tracking-label: 0.08em;
}
/* ──────────────────────────────────────────────────────────────
PLUME — playful · warm cream paper · tinted bands
Closer to actual playful than Pastel. Warm cream throughout,
alternating paper-2 bands on sections, hover-lift on cards, soft
rose accent. The page wants to feel friendly without being twee.
────────────────────────────────────────────────────────────── */
[data-theme="plume"] {
--color-paper: oklch(96% 0.020 70); /* warm cream */
--color-paper-2: oklch(94% 0.026 70); /* tinted band */
--color-paper-3: oklch(91% 0.030 70);
--color-rule: oklch(82% 0.022 70);
--color-rule-2: oklch(70% 0.024 70);
--color-muted: oklch(50% 0.022 60);
--color-neutral: oklch(36% 0.020 55);
--color-ink-2: oklch(30% 0.018 55);
--color-ink: oklch(22% 0.015 50);
--color-accent: oklch(68% 0.130 18); /* soft rose-pink */
--color-accent-ink: oklch(96% 0.020 70);
--color-focus: oklch(68% 0.130 18);
--font-display: "Bricolage Grotesque", "Geist", ui-sans-serif, system-ui, sans-serif;
--font-body: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif;
--font-serif: "Newsreader", ui-serif, Georgia, serif;
--font-label: "Geist Mono", ui-monospace, monospace;
--font-mono: "Geist Mono", ui-monospace, monospace;
--display-weight: 700;
--display-style: normal;
--text-display: clamp(2.75rem, 5vw + 0.75rem, 5rem);
--text-display-s: clamp(2rem, 3vw + 0.5rem, 3rem);
--tracking-display: -0.025em;
--tracking-tight: -0.012em;
--tracking-label: 0.06em;
}
/* ──────────────────────────────────────────────────────────────
PER-THEME COMPONENT SHAPE — radius, border weight, shadow.
Defaults (in :root above): square edges, 1 px border, no shadow.
@@ -890,4 +1082,14 @@
[data-theme="bloom"] { --radius-card: 16px; --radius-pill: 999px; --radius-input: 12px;
--shadow-card: 0 24px 48px -16px oklch(8% 0.04 35 / 0.6),
0 1px 2px oklch(8% 0.04 35 / 0.4); }
[data-theme="coral"] { --radius-card: 8px; --radius-pill: 999px; --radius-input: 6px;
--shadow-card: 0 1px 2px oklch(20% 0.01 50 / 0.06); }
[data-theme="violet"] { --radius-card: 6px; --radius-pill: 999px; --radius-input: 6px; }
[data-theme="aurora"] { --radius-card: 12px; --radius-pill: 999px; --radius-input: 10px;
--shadow-card: 0 16px 40px -16px oklch(11% 0.04 200 / 0.65),
0 1px 2px oklch(11% 0.04 200 / 0.4); }
[data-theme="halo"] { --radius-card: 8px; --radius-pill: 6px; --radius-input: 6px;
--shadow-card: 0 8px 22px -12px oklch(13% 0.02 60 / 0.5); }
[data-theme="plume"] { --radius-card: 14px; --radius-pill: 999px; --radius-input: 10px;
--shadow-card: 0 10px 28px -12px oklch(45% 0.10 18 / 0.16); }
+18 -18
View File
@@ -98,6 +98,16 @@
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>
<button class="banner__dot" type="button" data-theme-btn="coral" aria-label="Coral"
style="--dot: oklch(96.5% 0.005 50); --dot-edge: oklch(64% 0.165 28);"></button>
<button class="banner__dot" type="button" data-theme-btn="violet" aria-label="Violet"
style="--dot: oklch(99% 0.003 280); --dot-edge: oklch(58% 0.16 285);"></button>
<button class="banner__dot" type="button" data-theme-btn="aurora" aria-label="Aurora"
style="--dot: oklch(11% 0.025 200); --dot-edge: oklch(72% 0.170 200);"></button>
<button class="banner__dot" type="button" data-theme-btn="halo" aria-label="Halo"
style="--dot: oklch(13% 0.005 60); --dot-edge: oklch(74% 0.16 70);"></button>
<button class="banner__dot" type="button" data-theme-btn="plume" aria-label="Plume"
style="--dot: oklch(96% 0.020 70); --dot-edge: oklch(68% 0.130 18);"></button>
</div>
@@ -117,7 +127,7 @@
<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>.
Press <kbd>T</kbd> to see this page in <strong>22 shapes</strong>.
</span>
</aside>
</header>
@@ -317,10 +327,7 @@
<!-- Tile 01 — Tide -->
<article class="study-card">
<div class="study-card__media">
<video class="study-card__video" autoplay muted loop playsinline
poster="_tests/_thumbs/01-tide.png" aria-label="Tide page in motion">
<!-- USER: drop <source src="study/01-tide.mp4" type="video/mp4" /> here -->
</video>
<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">
@@ -340,10 +347,7 @@
<!-- Tile 02 — Tracejam -->
<article class="study-card">
<div class="study-card__media">
<video class="study-card__video" autoplay muted loop playsinline
poster="_tests/_thumbs/05-tracejam.png" aria-label="Tracejam page in motion">
<!-- USER: drop <source src="study/02-tracejam.mp4" type="video/mp4" /> here -->
</video>
<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">
@@ -363,10 +367,8 @@
<!-- Tile 03 — USER will fill -->
<article class="study-card" data-user-content>
<div class="study-card__media">
<video class="study-card__video" autoplay muted loop playsinline
poster="_tests/_thumbs/03-maple.png" aria-label="User study tile 3">
<!-- USER: drop <source src="study/03-<your-page>.mp4" type="video/mp4" /> here -->
</video>
<!-- USER: replace src with your screenshot when ready -->
<img class="study-card__img" src="_tests/_thumbs/03-maple.png" alt="Your study reference 3" loading="lazy" decoding="async" />
<span class="study-card__badge">03 · Yours</span>
</div>
<!-- USER CONTENT — replace each "—" with your DNA value. Keep the same shape. -->
@@ -387,10 +389,8 @@
<!-- Tile 04 — USER will fill -->
<article class="study-card" data-user-content>
<div class="study-card__media">
<video class="study-card__video" autoplay muted loop playsinline
poster="_tests/_thumbs/07-foundry.png" aria-label="User study tile 4">
<!-- USER: drop <source src="study/04-<your-page>.mp4" type="video/mp4" /> here -->
</video>
<!-- USER: replace src with your screenshot when ready -->
<img class="study-card__img" src="_tests/_thumbs/07-foundry.png" alt="Your study reference 4" loading="lazy" decoding="async" />
<span class="study-card__badge">04 · Yours</span>
</div>
<!-- USER CONTENT — replace each "—" with your DNA value. Keep the same shape. -->
@@ -1004,7 +1004,7 @@
<div class="foot__col">
<p class="foot__col-head">Catalog</p>
<ul>
<li>17 themes</li>
<li>22 themes</li>
<li>21 macrostructures</li>
<li>32 archetypes</li>
<li>45 slop-test gates</li>
+125 -5
View File
@@ -42,6 +42,11 @@ const THEMES = {
riso: "Riso",
quiet: "Quiet",
bloom: "Bloom",
coral: "Coral",
violet: "Violet",
aurora: "Aurora",
halo: "Halo",
plume: "Plume",
};
const STORAGE_KEY = "hallmark-theme";
@@ -67,6 +72,11 @@ const ARCHETYPES = {
riso: { hero: "quote-led", footer: "dense" },
quiet: { hero: "split", footer: "masthead" },
bloom: { hero: "marquee", footer: "masthead" },
coral: { hero: "split", footer: "masthead" },
violet: { hero: "split", footer: "masthead" },
aurora: { hero: "marquee", footer: "masthead" },
halo: { hero: "clipped", footer: "index" },
plume: { hero: "clipped", footer: "masthead" },
};
/* Theme genre map
@@ -87,20 +97,25 @@ const THEME_GENRES = {
sport: "editorial",
brutal: "editorial",
manifesto: "editorial",
// modern-minimal — Stripe / Linear / ElevenLabs school
// modern-minimal — Stripe / Linear / ElevenLabs school (3 themes)
quiet: "modern-minimal",
// atmospheric — Suno / Runway / dark-AI-tool school
coral: "modern-minimal",
violet: "modern-minimal",
// atmospheric — Suno / Runway / dark-AI-tool school (5 themes)
bloom: "atmospheric",
midnight: "atmospheric",
terminal: "atmospheric",
// playful — post-Linear soft school
aurora: "atmospheric",
halo: "atmospheric",
// playful — post-Linear soft school (2 themes)
pastel: "playful",
plume: "playful",
};
/* Locked hero title
The H1 string is the same across every theme. Only the visual
treatment swaps italic vs roman, serif vs sans, all-caps vs not.
The page is the demo: one sentence, sixteen distinct designs. */
The page is the demo: one sentence, twenty-two distinct designs. */
const HERO_TITLE = "A design skill that refuses to look AI-generated.";
/* Per-theme copy fixtures
@@ -451,6 +466,111 @@ const COPY = {
captionA: "Bloom",
captionB: "Late-night",
},
coral: {
eyebrow: "Modern minimal · warm-grey",
title: HERO_TITLE,
lede: "For the polished SaaS that wants warmth without losing discipline. Warm-grey paper, Geist throughout, a single coral accent kept under three percent of the view.",
ctaLabel: "Get started",
proofLabel: "Decisions",
proofA: "Warm-grey paper, not pure white",
proofB: "Geist + General Sans, one weight",
proofC: "Single coral accent · pill CTAs",
cta: "Get started",
stat: "1",
qualifier: "warm minimal · pill CTAs.",
mockStat: "1",
quote: "Restraint with warmth is harder than restraint without it.",
attrib: "Coral note",
salutation: "Hello.",
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",
},
violet: {
eyebrow: "Modern minimal · quiet violet",
title: HERO_TITLE,
lede: "Restrained near-black on near-white. Tight Geist throughout. A single quiet violet accent on focus rings — the rest is type, space, and rhythm.",
ctaLabel: "Get started",
proofLabel: "Decisions",
proofA: "Near-white paper · near-black ink",
proofB: "Geist tight tracking, single weight",
proofC: "Quiet violet · focus rings + small marks",
cta: "Get started",
stat: "1",
qualifier: "the Linear voice, not the brand.",
mockStat: "1",
quote: "The work that looks effortless is the work where the choices were made.",
attrib: "Violet note",
salutation: "Hello.",
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",
},
aurora: {
eyebrow: "Atmospheric · cool",
title: HERO_TITLE,
lede: "For the after-dark dev tool. Cool blue-green canvas, two atmospheric blooms behind the content, single cyan accent. Sentient body for warmth on the cool ground.",
ctaLabel: "Open it",
proofLabel: "Atmosphere",
proofA: "Dark cool canvas · two cool blooms",
proofB: "Geist display + Sentient body",
proofC: "Cyan accent, never gradient text",
cta: "Open it",
stat: "2",
qualifier: "atmospheric blooms · cool canvas.",
mockStat: "2",
quote: "The page should feel like the moment after a deploy goes green.",
attrib: "Aurora note",
salutation: "Online,",
letterBody: "A dark cool atmospheric theme — the dev-tool-after-dark register. Two cool blooms (cyan top-right, teal-green bottom-left). Geist display for confidence; Sentient body to keep the cool ground from feeling clinical.",
signoff: "— Aurora",
captionA: "Aurora",
captionB: "Late-shift",
},
halo: {
eyebrow: "Atmospheric · charcoal",
title: HERO_TITLE,
lede: "Less canvas, more content. Neutral charcoal page with a single warm-amber bloom around the hero — below that, the rest of the page is content-led on dark paper. The tool you actually work in.",
ctaLabel: "Get to work",
proofLabel: "Discipline",
proofA: "Charcoal canvas · one warm bloom up top",
proofB: "Geist throughout · single weight",
proofC: "Hero is the only atmospheric moment",
cta: "Get to work",
stat: "1",
qualifier: "moment of atmosphere · then content.",
mockStat: "1",
quote: "The atmosphere does its job at the top, then steps aside.",
attrib: "Halo note",
salutation: "Online,",
letterBody: "A dark theme for the working tool — the bloom lives only at the top of the page, around the hero. Below it the canvas is plain charcoal, content-led, no atmospheric distractions. Less Suno, more the IDE you actually open every day.",
signoff: "— Halo",
captionA: "Halo",
captionB: "Workshop",
},
plume: {
eyebrow: "Playful · warm cream",
title: HERO_TITLE,
lede: "Warm cream throughout. Alternating tinted bands on sections. Hover-lift on cards. A soft rose accent. Friendly without being twee — the page wants to feel approachable.",
ctaLabel: "Try it",
proofLabel: "Marks of the house",
proofA: "Warm cream paper · tinted bands on sections",
proofB: "Bricolage display + Geist body",
proofC: "Soft rose accent · hover-lift cards",
cta: "Try it",
stat: "1",
qualifier: "soft accent · friendly motion.",
mockStat: "1",
quote: "Soft is harder than serious; it has nowhere to hide.",
attrib: "Plume note",
salutation: "Hello,",
letterBody: "A playful theme that earns the word. Warm cream paper, alternating tinted bands so each section has its own register, soft drop shadows, hover-lift on cards. Friendly motion that responds to the user instead of performing for them.",
signoff: "Yours,",
captionA: "Plume",
captionB: "Late spring",
},
};
/* — Slot population ———————————————————————————————————— */
@@ -492,7 +612,7 @@ function buildDenseColophon(themeName) {
`# hallmark · v0.8.0 · ${themeName.toLowerCase()}`,
`# build: ${today} · MIT · powered by together ai`,
`#`,
`# stats: 21 macrostructures · 32 archetypes · 17 themes · 45 gates`,
`# stats: 21 macrostructures · 32 archetypes · 22 themes · 45 gates`,
`# catalog (16 named) + custom (per-brand, opt-in)`,
`#`,
`# repo: github.com/Luffixos/hallmark`,