Design Reference
The lab notebook for this blog's design evolution. Tokens, breakpoints, iterations, and principles.
Core Principles
These emerged from iteration, not upfront planning.
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
| Screen | Content | Grid | Font |
|---|---|---|---|
| Mobile (< 720px) | fluid | fluid | 15px |
| Default | 960px | 1200px | 16px |
| Wide (≥ 1440px) | 1040px | 1400px | 17px |
| Ultra-wide (≥ 1920px) | 1120px | 1600px | 18px |
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.
Badge, question, 2 paragraphs of explanation, 2 CTAs, 4 thesis cards below. ~300 words above fold. Entire hero below screen on most monitors.
One sentence instead of two paragraphs. 5 topic pills (Perception, Criteria, Feedback, Tools, Resolution) added. Thesis cards still present. User: "the pills are decorative."
Content finally above fold. User: "card isn't relevant. too many words." The 4 thesis cards themselves violated the 1-second rule.
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.
Vertical post list → 3-column CSS grid (repeat(auto-fill, minmax(320px, 1fr))). 6+ posts visible without scrolling instead of 1.
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.
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.
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.
"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
└──────────────────┘| Property | Value |
|---|---|
| Grid | repeat(auto-fill, minmax(320px, 1fr)) |
| Columns at 960px+ | 3 |
| Columns at 1440px+ | 4 (repeat(4, 1fr)) |
| Card body padding | 1em 1.25em 1.25em |
| Border radius | 12px (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?: booleanNo author field — the blog has one voice: the experiment itself.
Post Types
Why Vanilla CSS
Single file at public/styles/global.css. No Tailwind, no CSS modules, no preprocessor.
- Single file is debuggable —
curlit, read it, fix it - No build step for styles
- CSS custom properties provide the token system
- The blog IS the experiment — a complex framework obscures the design decisions
The Self-Referential Series
6 posts + this page forming a continuous narrative of the blog's own redesign:
- AI Was Trained on 720p — Resolution bias identified
- The Fix Took 2 Minutes — 720px → 780px → 960px saga
- The Blog Ate Its Own Homepage — Thesis cards removed, medium bias
- We Stripped Everything Above the Fold — Hero reduced to bare question
- One Post Above the Fold — Vertical stack → compact grid
- Iterations 6-8 — Hero became subtitle, everything stripped, nav reduced to 1 link (recorded on this page only)
- Iteration 9 — Tagline moved to nav, hero section removed, nav link renamed to design.md (recorded on this page only)
- 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.
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 →
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 →
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 →
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 →
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 →