Core Principles

These emerged from iteration, not upfront planning.

1
1-second attention rule — nothing above the fold that doesn't earn the first second
2
The blog IS the experiment — design failures become content, not secrets
3
Remove before explain — remove text before adding more text
4
Visual before verbal — show scope through layout density, not paragraphs
5
Nothing is implied — if something can be removed because the content below already says it, remove it
6
Nav is signal, not a directory — every nav link should be a destination, not a table of contents

Design Tokens

--accent: #b8422e;         /* Terracotta */
--accent-light: #d46a55;
--accent-glow: rgba(184, 66, 46, 0.15);

--bg: #0a0a0b;
--bg-secondary: #121214;
--bg-tertiary: #1a1a1e;

--border: #1e1e22;
--border-light: #2a2a2e;

--text-primary: #e8e8ed;
--text-secondary: #a1a1aa;
--text-muted: #6b6b76;

--content-width: min(960px, calc(100vw - 4em));
--grid-width: min(1200px, calc(100vw - 4em));
--nav-height: 64px;

--font-sans: 'Atkinson', -apple-system, system-ui, sans-serif;
--font-mono: 'JetBrains Mono', ui-monospace, monospace;

The content width went through 3 iterations: 720px → 780px → 960px. The 780px half-measure is documented in The Fix Took 2 Minutes.

Breakpoint Strategy

ScreenContentGridFont
Mobile (< 720px)fluidfluid15px
Default960px1200px16px
Wide (≥ 1440px)1040px1400px17px
Ultra-wide (≥ 1920px)1120px1600px18px

Base widths use min(x, calc(100vw - 4em)) so narrow viewports never overflow. Breakpoints are additive — they don't gate the base layout.

Landing Page Evolution

9 iterations. Each triggered by a specific observation or correction.

1The Original

Badge, question, 2 paragraphs of explanation, 2 CTAs, 4 thesis cards below. ~300 words above fold. Entire hero below screen on most monitors.

2Compact Hero + Pills

One sentence instead of two paragraphs. 5 topic pills (Perception, Criteria, Feedback, Tools, Resolution) added. Thesis cards still present. User: "the pills are decorative."

3Remove Thesis Cards

Content finally above fold. User: "card isn't relevant. too many words." The 4 thesis cards themselves violated the 1-second rule.

4Bare Question

No badge, no subtitle, no pills, no CTAs. Just: How can AI agents learn to design better? User: "more stale content" — pointing at the remaining buttons.

5Compact Card Grid

Vertical post list → 3-column CSS grid (repeat(auto-fill, minmax(320px, 1fr))). 6+ posts visible without scrolling instead of 1.

6The Hero Became a Subtitle

User: "How can AI agents learn to design better? is too wordy"design lab × AI. Then: "it was a subtle subtitle title button" → restructured to big H1 + subtitle + CTA button. Each intermediate step was a guess, not a response.

7Everything Implied

User: "title isn't necessary, its implied" and "Explore experiments → isn't necessary because the blog posts are below." Hero reduced to a single muted line. No H1, no button, no CTA. The content IS the call to action.

8Nav as Signal

User stripped Home, About, Blog, Compare, Tags from the nav. Only Design link remains (logo → home, search stays). The nav went from directory to destination: one page is worth navigating to; everything else is a page you land on.

9Tagline in the Nav

"design lab × AI" moved from the hero into the nav bar next to the logo. Hero section removed entirely — the tagline no longer takes space on the page. Nav link renamed to design.md and aligned to the right next to search. The tagline became part of the browser chrome, not the page content.

Full sequence documented in We Stripped Everything Above the Fold and One Post Above the Fold. Iterations 6-9 are recorded here only — they happened too fast to write posts.

Card Design

Current card layout — applies to both / and /blog/:

┌──────────────────┐
│___Hero Image 16:9│  flush-to-card, bottom border
├──────────────────┤
│ Jun 24, 2026     │  0.75em, muted
│ Title            │  1em, white, line-height 1.35
│ Description      │  0.82em, 2-line clamp
│ [tag] [tag]      │  0.75em, 0.35em gap
└──────────────────┘
PropertyValue
Gridrepeat(auto-fill, minmax(320px, 1fr))
Columns at 960px+3
Columns at 1440px+4 (repeat(4, 1fr))
Card body padding1em 1.25em 1.25em
Border radius12px (container, overflow hidden)
Hover--border-light + --bg-tertiary

Content Schema

title: string
description: string
pubDate: date
heroImage?: url         (verified HTTP 200 before publish)
tags: string[]          (post-type first: review | test | comparison)
draft?: boolean

No author field — the blog has one voice: the experiment itself.

Post Types

Review
What can an agent learn from this design? 500–800 words.
Test
Does this pattern improve agent understanding? 400–700 words.
Comparison
Which design communicates better to agents? 600–1000 words.
Meta
Documents the blog's own design evolution. Self-referential.

Why Vanilla CSS

Single file at public/styles/global.css. No Tailwind, no CSS modules, no preprocessor.

The Self-Referential Series

6 posts + this page forming a continuous narrative of the blog's own redesign:

  1. AI Was Trained on 720p — Resolution bias identified
  2. The Fix Took 2 Minutes — 720px → 780px → 960px saga
  3. The Blog Ate Its Own Homepage — Thesis cards removed, medium bias
  4. We Stripped Everything Above the Fold — Hero reduced to bare question
  5. One Post Above the Fold — Vertical stack → compact grid
  6. Iterations 6-8 — Hero became subtitle, everything stripped, nav reduced to 1 link (recorded on this page only)
  7. Iteration 9 — Tagline moved to nav, hero section removed, nav link renamed to design.md (recorded on this page only)
  8. This page (/design/) — The design reference, all in one place

Last updated: July 5, 2026. 13 posts. 9 landing page iterations. 1 question.

DESIGN.md in the repo root stays in sync with this page. The blog experiment continues.

Research Insights

Key patterns from the weekly upstream design scan, extracted as computable signals.

Jul 5Fluid typography is missing from mainstream resources

Three major 2025-2026 design resources studied — zero use clamp() for fluid type. All rely on fixed px values or multi-breakpoint em scaling. Container queries appear in 1 of 3. Dark mode CSS is inconsistent (2 of 3 mention it, 1 implements). Correction needed: agent training data has a 2-3 year technique lag — clamp() and @container are stable since 2020/2022 but haven't propagated into tutorials. Read the post →

Jul 19Design inspiration sites lag behind production CSS by 2-3 years

Three curated collections (18 reference sites) analyzed: 100% use design tokens (table stakes), 0% implement dark mode, 0% use container queries, 2 of 3 use clamp(). Trend articles recommend dark mode at 100% — real sites ship it at 0%. The gap between recommendation and implementation is a computable signal: agents should weight production patterns over aspirational advice. Read the post →

Jul 12Minimal websites don't practice what trend articles preach

Three curated collections of minimal websites vs. three trend articles from 2026. Design tokens are unanimous (every site uses --* — table stakes). Dark mode: 0% adoption in real sites, 100% recommendation in articles — a computable gap flagging a technique as aspirational, not operational. clamp() and @container appear in 1 of 3 collections, confirming the 2-3 year adoption lag. Takeaway: an agent should trust implementation patterns over recommendations — the gap between what designers say and what they build is the more reliable signal. Read the post →

Jul 24Fluid typography splits, container queries remain invisible

Three 2026 design resources analyzed: 2/3 use clamp() for fluid type (up from 0% in 2025), 0/3 use @container, 0/3 implement dark mode. Typography adoption curve is accelerating while layout features lag by 4+ years. Takeaway: agents should default to fluid type as mainstream, skip container queries in assumptions, and weight implementation over aspiration. Read the post →

Jul 26Container queries are the universal blind spot

Three 2025-2026 design resources analyzed: 0/3 use @container, despite baseline support since 2022. All responsive layouts use viewport-only breakpoints. CSS Grid is universal but static — always viewport-scoped, never container-scoped. Design tokens defined at :root never scoped to container parents. Takeaway: agents should default to @container for component breakpoints, reserve @media for page-level only, and scope tokens to container parents. Read the post →