From f5f4a2ceb0ff302f2e69fb33679501611eadee32 Mon Sep 17 00:00:00 2001
From: Youssef
Date: Thu, 6 Aug 2026 14:41:26 +0100
Subject: [PATCH] Add Grid, the twenty-first theme
Swiss neo-grotesque systems design: a near-white cool sheet with the
twelve-column hairline grid painted behind the content rather than implied,
one heavy Archivo run lowercase and slammed left, and exactly one signal red
used as a geometric mark. It fills the editorial cluster's neo-grotesque slot,
which until now was serif-led on every one of its members.
Skill side: the theme spec, and the catalog count from twenty to twenty-one in
the four places SKILL.md states it.
Site side: the token block, the switcher entry, the twenty-first dropdown dot,
Archivo added to the font load, the Buro Grid example page with its thumbnail,
and an entry in the theme contact sheet.
Not added to scroll-demos.json on purpose. Grid's motion is near-zero by
design, no reveals and no parallax, so a scroll recording would be an empty
file advertising something the theme refuses to do.
README carries the new count only, no new section.
---
README.md | 4 +-
site/_tests/_thumbs/grid-01.jpg | Bin 0 -> 292288 bytes
site/_tests/all-themes.html | 9 +-
site/css/tokens.css | 44 ++
site/examples/grid-01/index.html | 467 ++++++++++++++++++++++
site/index.html | 14 +-
site/js/main.js | 33 +-
skills/hallmark/SKILL.md | 10 +-
skills/hallmark/references/themes/grid.md | 132 ++++++
9 files changed, 695 insertions(+), 18 deletions(-)
create mode 100644 site/_tests/_thumbs/grid-01.jpg
create mode 100644 site/examples/grid-01/index.html
create mode 100644 skills/hallmark/references/themes/grid.md
diff --git a/README.md b/README.md
index a615a80..974d732 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
**A design skill for Claude Code, Cursor, and Codex that refuses to look AI-generated.**
-[Live demo →](https://www.usehallmark.com) · twenty themes · four verbs · press `T` to cycle.
+[Live demo →](https://www.usehallmark.com) · twenty-one themes · four verbs · press `T` to cycle.
Made by Together AI.
@@ -10,7 +10,7 @@ Made by Together AI.
-Hallmark picks a macrostructure for the brief, dresses it in one of twenty themes, runs fifty-seven slop-test gates plus a pre-emit self-critique, and refuses the on-distribution defaults every LLM was trained into. Two pages by Hallmark for two different briefs feel like different sites, not colour-swaps of the same template.
+Hallmark picks a macrostructure for the brief, dresses it in one of twenty-one themes, runs fifty-seven slop-test gates plus a pre-emit self-critique, and refuses the on-distribution defaults every LLM was trained into. Two pages by Hallmark for two different briefs feel like different sites, not colour-swaps of the same template.
---
diff --git a/site/_tests/_thumbs/grid-01.jpg b/site/_tests/_thumbs/grid-01.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ec113723fcfd7cb3e087be932e019761b46ab84a
GIT binary patch
literal 292288
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
Büro Grid builds identity, wayfinding, and editorial systems for institutions that plan in decades. We draw the grid first, so every decision after it has somewhere to stand.
+
Basel, since 2009 Working in DE / EN
+
+
+
+
+
+
+
Structure before surface
+
+
+
+
Practice
+
Identity systems, signage programmes, and editorial grids. Each project begins as a set of rules, never as a single picture.
+
+
+
Method
+
Fixed modules, one measure, a single accent. The system has to survive twenty years of new hands, new content, and new signage.
+
+
+
Standort
+
Based in Basel, working across the institutional landscape in German and English. On site whenever the building itself needs us.
+
+
diff --git a/site/js/main.js b/site/js/main.js
index ca7eeea..dd36a28 100644
--- a/site/js/main.js
+++ b/site/js/main.js
@@ -60,6 +60,7 @@ const THEMES = {
carnival: "Carnival",
lumen: "Lumen",
cobalt: "Cobalt",
+ grid: "Grid",
};
const STORAGE_KEY = "hallmark-theme";
@@ -88,6 +89,7 @@ const ARCHETYPES = {
lumen: { hero: "marquee", footer: "colophon" },
hum: { hero: "hum", footer: "colophon" },
cobalt: { hero: "cobalt", footer: "colophon" },
+ grid: { hero: "marquee", footer: "colophon" },
};
/* — Theme → genre map ——————————————————————————————————
@@ -125,7 +127,7 @@ const THEME_GENRES = {
/* — 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, twenty distinct designs. */
+ The page is the demo: one sentence, twenty-one distinct designs. */
const HERO_TITLE = "A design skill that refuses to look AI-generated.";
/* — Per-theme copy fixtures —————————————————————————————
@@ -228,7 +230,7 @@ const COPY = {
quote: "An almanac is a book that knows where to look.",
attrib: "Almanac, frontispiece",
salutation: "Reference note,",
- letterBody: "This page is a reference, not an argument. The numbers are the point: 21 macrostructures, 50 archetypes, 20 themes, 57 slop-test gates. Cross-referenced so the next page Hallmark builds is genuinely different from the last.",
+ letterBody: "This page is a reference, not an argument. The numbers are the point: 21 macrostructures, 50 archetypes, 21 themes, 57 slop-test gates. Cross-referenced so the next page Hallmark builds is genuinely different from the last.",
signoff: "— editor",
captionA: "Vol. III",
captionB: "Plate 12",
@@ -460,7 +462,7 @@ const COPY = {
carnival: {
eyebrow: "NO TEMPLATES · NO DEFAULTS",
title: HERO_TITLE,
- lede: "20 themes that refuse to blend in. Pick one and the whole page changes — the bones, not the paint.",
+ lede: "21 themes that refuse to blend in. Pick one and the whole page changes — the bones, not the paint.",
ctaLabel: "Install",
proofLabel: "ON THE BILL",
proofA: "21 page-shapes, 50 archetypes",
@@ -472,7 +474,7 @@ const COPY = {
quote: "A PAGE THAT HEDGES IS A PAGE THAT FAILS.",
attrib: "CARNIVAL",
salutation: "WE PRINT POSTERS, NOT TEMPLATES.",
- letterBody: "Every model was trained on the same page. Carnival refuses it — loud type, duo-tone ink, ornaments that mean it. 20 themes in the catalog, and not one of them whispers.",
+ letterBody: "Every model was trained on the same page. Carnival refuses it — loud type, duo-tone ink, ornaments that mean it. 21 themes in the catalog, and not one of them whispers.",
signoff: "— CARNIVAL",
captionA: "BILL 01",
captionB: "OUT NOW",
@@ -492,7 +494,7 @@ const COPY = {
quote: "two briefs, two pages — not one template, recoloured.",
attrib: "lumen",
salutation: "built to refuse the default.",
- letterBody: "every model emits the same page. lumen is the part that refuses — lowercase classical serif, one accent verb, a hand-built apparatus where the orb used to be. twenty themes in the catalog, and the numbers hold under load.",
+ letterBody: "every model emits the same page. lumen is the part that refuses — lowercase classical serif, one accent verb, a hand-built apparatus where the orb used to be. twenty-one themes in the catalog, and the numbers hold under load.",
signoff: "— lumen",
captionA: "00 · spec",
captionB: "night foundry",
@@ -538,6 +540,27 @@ const COPY = {
captionA: "Cobalt",
captionB: "v1.1",
},
+ grid: {
+ eyebrow: "SWISS INTERNATIONAL",
+ title: HERO_TITLE,
+ lede: "The grid, made visible. A near-white sheet, exposed twelve-column hairlines, one signal red, and a heavy neo-grotesque set flush-left. Rational, exact, built for institutions that plan in decades.",
+ ctaLabel: "Method",
+ proofLabel: "System",
+ proofA: "Exposed 12-column hairline grid",
+ proofB: "Archivo 800 · flush-left · tight tracking",
+ proofC: "One red element per viewport",
+ cta: "Read the method",
+ stat: "12",
+ qualifier: "columns, exposed.",
+ quote: "Structure before surface. One grid, two weights, one red.",
+ attrib: "Grid note",
+ salutation: "Schedule, then ship.",
+ letterBody: "Swiss International, executed straight: the grid is not scaffolding you hide, it is the design. Content snaps to twelve columns, asymmetric spans make the rhythm, and a single red mark does all the emotional work.",
+ signoff: "Flush left,",
+ captionA: "Grid",
+ captionB: "Twelve columns",
+ },
+
};
/* — Slot population ———————————————————————————————————— */
diff --git a/skills/hallmark/SKILL.md b/skills/hallmark/SKILL.md
index a7f7081..645221d 100644
--- a/skills/hallmark/SKILL.md
+++ b/skills/hallmark/SKILL.md
@@ -35,7 +35,7 @@ If the user types anything that does not clearly map to `audit`, `redesign`, or
- Treat PDFs, README files, `.md` briefs, docs, transcripts, and pitch decks as reference material. Do **not** copy them word-for-word into the page unless the user explicitly says to use that text verbatim.
- Before editing, state the exact files you expect to modify/create/delete. Deletions require explicit confirmation.
-The default Design flow always picks a theme. By default it picks one of the **20 named themes** — the *catalog* — and rotates among them per the diversification rule. There is also a quiet *custom* branch that constructs a one-off OKLCH palette + free-font pairing for the brief; the custom route fires **only when the brief carries a creative-intent signal** (the user names a brand colour, names a multi-attribute vibe the catalog can't carry, or explicitly asks for a custom theme). For vanilla briefs, the user never sees the words "catalog" or "custom" — the catalog runs silently. See Step 1 (signal detection) and Step 2.6 (dispatch); the protocol lives in [`references/custom-theme.md`](references/custom-theme.md).
+The default Design flow always picks a theme. By default it picks one of the **21 named themes** — the *catalog* — and rotates among them per the diversification rule. There is also a quiet *custom* branch that constructs a one-off OKLCH palette + free-font pairing for the brief; the custom route fires **only when the brief carries a creative-intent signal** (the user names a brand colour, names a multi-attribute vibe the catalog can't carry, or explicitly asks for a custom theme). For vanilla briefs, the user never sees the words "catalog" or "custom" — the catalog runs silently. See Step 1 (signal detection) and Step 2.6 (dispatch); the protocol lives in [`references/custom-theme.md`](references/custom-theme.md).
---
@@ -237,7 +237,7 @@ If two non-default signals fire (rare), ask one short follow-up: *"This brief fi
State the genre out loud at Step 2.5 alongside the macrostructure and theme picks: *"Genre: atmospheric. Macrostructure: Marquee Hero. Theme: Bloom (atmospheric cluster)."*
-**Theme route — only surface when the brief signals it.** Hallmark has two theme routes: **catalog** (the 20 named themes — Specimen, Atelier, Brutal, Newsprint, Studio, Manifesto, Terminal, Midnight, Almanac, Garden, Riso, Sport, Bloom, Coral, Cobalt, Aurora, Editorial, Carnival, Lumen, Hum) and **custom** (made-to-measure for one brief — a *tuned* OKLCH palette + free-font pairing on Hallmark's structures, or, when the brief's structure itself is the ask, a fully *bespoke* page designed from first principles; bound by every slop-test gate either way; see [`references/custom-theme.md`](references/custom-theme.md)). **Catalog is the default.** The catalog rotation is *scoped to the genre's theme cluster* — atmospheric rotates Bloom/Midnight/Terminal/Aurora/Lumen, modern-minimal rotates Coral/Cobalt, playful stays on Hum, editorial walks the remaining twelve (Specimen, Atelier, Brutal, Newsprint, Studio, Manifesto, Almanac, Garden, Riso, Sport, Editorial, Carnival). Do **not** offer the user a choice on every prompt — that's friction, not discipline. Surface the catalog/custom fork only when the brief carries one of these signals:
+**Theme route — only surface when the brief signals it.** Hallmark has two theme routes: **catalog** (the 21 named themes — Specimen, Atelier, Brutal, Newsprint, Studio, Manifesto, Terminal, Midnight, Almanac, Garden, Riso, Sport, Bloom, Coral, Cobalt, Aurora, Editorial, Carnival, Lumen, Hum, Grid) and **custom** (made-to-measure for one brief — a *tuned* OKLCH palette + free-font pairing on Hallmark's structures, or, when the brief's structure itself is the ask, a fully *bespoke* page designed from first principles; bound by every slop-test gate either way; see [`references/custom-theme.md`](references/custom-theme.md)). **Catalog is the default.** The catalog rotation is *scoped to the genre's theme cluster* — atmospheric rotates Bloom/Midnight/Terminal/Aurora/Lumen, modern-minimal rotates Coral/Cobalt, playful stays on Hum, editorial walks the remaining thirteen (Specimen, Atelier, Brutal, Newsprint, Studio, Manifesto, Almanac, Garden, Riso, Sport, Editorial, Carnival, Grid). Do **not** offer the user a choice on every prompt — that's friction, not discipline. Surface the catalog/custom fork only when the brief carries one of these signals:
- The user explicitly says **custom theme** / **tailored to our brand** / **make it ours** / **something unique** / **play with the colors and fonts**.
- The user names a **specific brand colour** as the anchor (e.g., "use our terracotta", "the brand red is hex #c0392b", "anchor on sea-blue").
@@ -248,7 +248,7 @@ If any of those fires, ask one short follow-up before picking: *"This brief read
**Custom has two depths** — *tuned* (a palette + fonts on Hallmark's structures) and *bespoke* (a page designed from first principles, own structure too) for when the brief's **structure itself** is the ask: "no theme / from scratch / fully bespoke", or a page-shape no catalog macrostructure fits. Both fire the one fork above, default to catalog on silence, and **pass every slop-test gate** — the depth simply follows the brief. See [`references/custom-theme.md`](references/custom-theme.md) § Bespoke depth.
-If none of the signals fires, **proceed with catalog silently. Do not mention the fork.** Most briefs don't need a custom theme — the catalog's 20 themes plus the rotation rule already deliver structural variety. See Step 2.6 for the dispatch.
+If none of the signals fires, **proceed with catalog silently. Do not mention the fork.** Most briefs don't need a custom theme — the catalog's 21 themes plus the rotation rule already deliver structural variety. See Step 2.6 for the dispatch.
**If the user opts out or skips fields** (says "go ahead", "you pick", "skip", "just build it", "don't ask", answers some fields and leaves others blank, or simply doesn't engage with the question after one prompt):
@@ -336,10 +336,10 @@ By the time you reach this step, one of four things is true:
0. **A `study` diagnosis was emitted earlier in this conversation and the user is asking to build from it** (phrases: *"build it"*, *"make it"*, *"use this DNA"*, *"build with this"* — immediately following the diagnosis) → theme route is **studied-DNA**. **Skip catalog/custom dispatch entirely.** The studied paper OKLCH, accent OKLCH, type roles (with named candidates), macrostructure, and nav/footer archetypes from the diagnosis become the locked system for this build. Diversification is suspended — you're following an external DNA, not rotating the catalog. The Step 6 stamp records `theme: studied-DNA (source: )` plus the actual OKLCH/font values inline. **If the user later pivots with phrases like *"use Newsprint instead"* / *"ignore the DNA"* / *"rotate to a different theme"*,** route back to the normal dispatch below and resume diversification. Continue to Step 3.
1. **The user named custom** (because they said so, or because Step 1's signal detection fired and they confirmed) → load [`references/custom-theme.md`](references/custom-theme.md). For a **tuned** custom: ask the **one** follow-up (vibe in 4–8 words + optional anchor colour), construct the OKLCH palette + free-font pairing, compute the three axis values (paper-band / display-style / accent-hue). If the brief's **structure itself** is the ask (signal 5 — "from scratch / no theme", or a page-shape no catalog macrostructure fits), take the **bespoke** depth instead: design the palette, type, **and** structure from first principles (custom-theme.md § Bespoke depth). **Every slop-test gate still fires either way.** Then continue to Step 3.
-2. **The user named catalog** (or implicitly accepted it by not naming custom) → pick one of the 20 named themes per the diversification rule above. Existing flow — continue to Step 3.
+2. **The user named catalog** (or implicitly accepted it by not naming custom) → pick one of the 21 named themes per the diversification rule above. Existing flow — continue to Step 3.
3. **Neither was discussed** (Step 1's signals didn't fire — vanilla brief) → default to **catalog**. Do not pause. Do not ask. Continue to Step 3.
-**Custom is a quiet branch, not a default question.** Most briefs route to catalog and the user never sees the words "catalog" or "custom." The 20 named themes plus the rotation rule already deliver structural variety; the fork is reserved for when the brief specifically asks for a tuned look the catalog can't carry.
+**Custom is a quiet branch, not a default question.** Most briefs route to catalog and the user never sees the words "catalog" or "custom." The 21 named themes plus the rotation rule already deliver structural variety; the fork is reserved for when the brief specifically asks for a tuned look the catalog can't carry.
A custom theme is a **complete** OKLCH palette + font pairing tuned to the brief — not a one-off colour swap, not an excuse to bypass the rules. Every constraint in [`color.md`](references/color.md), [`typography.md`](references/typography.md), and [`anti-patterns.md`](references/anti-patterns.md) still applies. The 58 slop-test gates fire unchanged. The Step 5 preview block surfaces the palette + pairing in plain text **before** any code is emitted, so the user can redirect.
diff --git a/skills/hallmark/references/themes/grid.md b/skills/hallmark/references/themes/grid.md
new file mode 100644
index 0000000..a4de0f2
--- /dev/null
+++ b/skills/hallmark/references/themes/grid.md
@@ -0,0 +1,132 @@
+# Theme - Grid
+
+Swiss neo-grotesque systems design: the object-poster and transit-signage school, executed on a **near-white cool sheet with an exposed 12-column hairline grid, one heavy grotesk, and exactly one signal red used as a geometric mark**. Giant lowercase Archivo slams to the left margin, the column rules stay visible behind the content, and every surface butts against a hairline. It reads like a wayfinding manual: rational, gridded, set once and built to outlast its brief.
+
+The material, in one line: **a visible column grid, one grotesk, and one red square.**
+
+> **The editorial exception.** The editorial cluster is otherwise serif-led (Newsprint, Editorial, Specimen). Grid is its Swiss neo-grotesque slot: no serif anywhere, structure carried by an exposed grid and hairlines, warmth carried by one red. A brief wanting a roman serif or a soft column is a different editorial theme.
+
+## Axes (diversification)
+
+- **Paper band** - **light**, cool near-white (`--color-paper: oklch(99% 0.003 255)`, faintly cool, never `#fff`). Stepped at `paper-2 97.2%` and `paper-3 94.5%`. Ink is cool near-black `--color-ink: oklch(16% 0.010 255)`.
+- **Display style** - **grotesk-heavy** (Archivo **800**, `--display-weight: 800`), run **lowercase** at `--tracking-display: -0.045em`. Heavy plus lowercase is the differentiator against every uppercase-condensed and serif option.
+- **Accent hue** - **warm signal red** (`--color-accent: oklch(55% 0.21 28)`), one saturated red near 28°, used as a square, a bar, a period, never a wash. `--color-focus` is the same red.
+
+## Reference register
+
+Vitra, Braun, the Vignelli canon, Museum fur Gestaltung, the Swiss International poster tradition. The material to match: the institutional identity manual and the transit-signage system - a modular grid drawn in public, one grotesk, one red, no image needed. When in doubt, ask whether this reads like a systems manual or like a marketing template, and keep the former. Never name any of these in the output.
+
+## Typography
+
+**Archivo only, one family across the whole page** (400/500/600/700/800). Swiss discipline comes from weight, scale, and tracking, not from a second family. `--font-serif` and `--font-mono` resolve to unused fallbacks; do not load them.
+
+- **Display** - Archivo 800, **lowercase**, `clamp(52px, 10.5vw, 136px)`, `letter-spacing: -0.045em`, `line-height: 0.9`. Slammed to the left margin, edge-aligned to the grid.
+- **Body** - Archivo 400, 16px, `line-height: 1.5`.
+- **Label voice** - Archivo uppercase at 12px, weight 600, `letter-spacing: 0.09em`, `--color-muted`. It sets captions, table headers, meta rows, folios, units, and index numbering - the quiet caps counterpoint to the giant lowercase display. It never sits above a heading as a kicker.
+
+## Material
+
+- **The exposed 12-column hairline grid is the theme.** A `repeating-linear-gradient` of 1px `--color-rule` lines every `calc(100% / 12)`, painted behind the content, capped to the shell width. The grid is content, not scaffolding to delete, and content rides `repeat(12, minmax(0,1fr))` on top of it.
+- **Red only as a geometric mark, under 5% of any viewport.** A solid `0.52em` square where a full stop would fall, a short block terminating a row, a `3px` bar over a head. Never a fill wash, never a gradient, never a second colour.
+- **Hairlines and ink rules do all the structure; zero cards.** `--radius-card: 0`, `--shadow-card: none`. Faint `--color-rule` hairlines split cells, a 1px-to-2px solid `--color-ink` rule tops a section, and content butts flush against it. No boxes, no float, no drop shadow.
+- **Cells, not tiles.** Where the page needs repeated units, they are equal cells of the same grid divided by `border-inline-start` hairlines, sharing the band's top and bottom rules. The band reads as one ruled object, not as a row of separate objects.
+- **`::selection` is red on paper.** The one place the accent floods anything.
+
+**Shapes Grid suits** (affinities, never requirements): a numbered index of full-width rows riding the 12 columns, with a hairline between fields and a hover tint; a type specimen where the grid is the exhibit; figures set in bordered cells with caps labels beneath.
+
+## Motion
+
+Near-zero. No reveals, no parallax, no autoplay. The only motion is hover micro-state: a row background shifts to `--color-paper-2` and its title slides 8px, links underline, a bordered surface shifts its border to red. Everything transitions in ~0.18-0.2s ease. Smooth scroll only, and `prefers-reduced-motion: reduce` kills transitions and `scroll-behavior`.
+
+## Do-nots (this theme's own failure modes)
+
+- **Never hide the grid.** The rails stay visible. Deleting them because they look like scaffolding removes the theme.
+- **Never uppercase display, never a serif, never a mono body.** Grid's display is lowercase Archivo; uppercase-condensed is Manifesto or Brutal, and the second family never arrives.
+- **Never a dark ground, and never a 3px black rule boxing a solid block.** A dark statement page is Manifesto; marker-weight structure is Brutal. Grid is a 99% sheet drawn with a 1px pencil.
+- **Never a second accent, a gradient, or a red wash.** One red, geometric, under 5%.
+- **Never a card, a radius, or a drop shadow.** Depth is hairlines and ink rules.
+- **Never a centred hero.** Slam left.
+
+## Macrostructure affinity
+
+**Grid loves these.**
+
+- **Index-First** - a numbered register of full-width rows riding the twelve columns, hairline between fields *(canonical - grid-01)*
+- **Type Specimen** - the grid is the exhibit and the type is the subject
+- **Catalogue** - equal ruled cells sharing the band's top and bottom rules
+- **Portfolio Grid** - work as a modular register, not as cards
+- **Split Studio** - when a studio's two halves each want their own column span
+
+## Macrostructure rejection
+
+**Grid refuses these.**
+
+- **Photographic** - Grid needs no image; the grid is the picture
+- **Manifesto** - dark, uppercase and shouted; Grid is a light sheet drawn with a 1px pencil
+- **Quote-Led** - too intimate and too centred; Grid slams left
+- **Bento Grid** - bento is boxes with radii; Grid is cells divided by hairlines, zero radius
+
+## Voice fixtures
+
+Rational, plainspoken, institutional. Name the system, the place, the year concretely. No hype.
+
+- *"Schedule, then ship."*
+- *"Identity, wayfinding, and editorial systems for institutions that plan in decades."*
+- *"We draw the grid first, so every decision after it has somewhere to stand."*
+- *"Basel, since 2009. Working in DE / EN."*
+- *"Twelve columns. One grotesk. One red."*
+
+Never any of: *seamless, robust, cutting-edge, leverage, synergy, revolutionary, unlock, supercharge, elevate, curated, bespoke*. Never "click here." Name the system, the city, the year.
+
+## How Grid differs from its neighbours
+
+| vs | difference |
+|---|---|
+| **Manifesto** | Manifesto is a **dark** ground (`oklch(10% 0.005 60)`), Anton 400 **uppercase** at `--lh-tight: 0.86`, red `#E51A1A`. Grid is a **light** sheet (`oklch(99% 0.003 255)`), Archivo **800 lowercase**, red `oklch(55% 0.21 28)`. Same "one red, type carries it" DNA, opposite value and case. |
+| **Cobalt** | Cobalt is modern-minimal: electric cobalt `oklch(58% 0.20 256)`, Space Grotesk plus JetBrains Mono, graphite code surfaces, 6-10px radii. Grid is editorial: red accent, single-family Archivo, an exposed 12-column grid, zero radius, no code. Blue instrument vs red Swiss manual. |
+| **Brutal** | Both are light near-neutral sheets with one red and zero radius, but Brutal draws with **3px** black rules (`--color-rule: oklch(12%)`) boxing solid inverted blocks in Albert Sans 700 **uppercase**. Grid draws with **1px** hairlines (`--color-rule: oklch(88%)`) painting a **visible column grid**, Archivo 800 **lowercase**, no solid panels. Marker vs pencil; shout vs quiet. |
+
+## When the brief routes here
+
+*identity · brand system · wayfinding · signage · design studio · type specimen · editorial grid · institution · museum · archive · index · directory · systems · modular · Swiss · grotesque · manual · programme*. Categories: design and branding studios, cultural institutions, publishers, specimens and catalogs, portfolio indexes. Tone: rational, systematic, precise, institutional, disciplined, timeless, calm-authoritative.
+
+Warm, consumer, image-led, or serif-editorial briefs route elsewhere. When the brief wants a visible grid, one grotesk, and one red, it is Grid.
+
+## Build hint
+
+```html
+
+```
+
+```css
+html, body { overflow-x: clip; }
+body { background: var(--color-paper); color: var(--color-ink);
+ font-family: var(--font-body); font-size: 16px; line-height: 1.5; }
+
+/* THE ground: the exposed 12-column hairline grid, painted behind the content */
+.rails {
+ position: absolute; inset: 0; z-index: 0; pointer-events: none;
+ max-width: 1280px; margin-inline: auto;
+ background-image: repeating-linear-gradient(to right,
+ var(--color-rule) 0, var(--color-rule) 1px,
+ transparent 1px, transparent calc(100% / 12));
+}
+
+h1, h2 { font-family: var(--font-display); font-weight: var(--display-weight);
+ font-size: clamp(52px, 10.5vw, 136px); letter-spacing: var(--tracking-display);
+ line-height: 0.9; text-transform: lowercase; }
+
+.period { /* the one signal, as a mark */
+ display: inline-block; width: 0.52em; height: 0.52em;
+ background: var(--color-accent);
+}
+
+::selection { background: var(--color-accent); color: var(--color-accent-ink); }
+
+@media (prefers-reduced-motion: reduce) {
+ html { scroll-behavior: auto; }
+ * { transition-duration: 0.01ms !important; }
+}
+```
+
+Grid supplies the sheet, the rails, the one grotesk, and the one red. What rides those twelve columns is the brief's business, not the theme's.