name: wcygan-net-design description: > Design system and UI/UX conventions for wcygan.net — a TanStack Start + Tailwind v3 personal blog with a minimal, readable, editorial aesthetic. Auto-loads when working in /Users/wcygan/Development/wcygan.net, editing src/styles/app.css, src/routes/__root.tsx, or any route/component/MDX post on that site. Use when styling pages, adding routes, writing MDX posts, touching the header/nav/footer chrome, or changing colors, type, spacing, or layout. Keywords: wcygan.net, wcygan blog, personal site design, minimal blog design, system fonts, primary blue, link blue, cornflower blue, bio-highlight banner, post-list, blog-post, 800px container, MDX frontmatter, Mermaid diagram, Shiki, Tailwind v3, TanStack Start blog, __root chrome, design.md, app.css
wcygan.net Design System
Minimal, text-first personal blog. The aesthetic is editorial minimalism with one committed cornflower-blue accent — no cards, no gradients, no drop shadows, no web fonts. System fonts, 800px column, tight vertical rhythm (a deliberate move away from the old "30px between every block" rule — see layout.md for the current scale).
Project root: /Users/wcygan/Development/wcygan.net
Prime directives
- The aesthetic is already chosen. Do not introduce new directions (brutalist, glassmorphic, neon, etc.) without explicit request. This is a reader's blog.
src/styles/app.cssanddesign.mdare the source of truth. If a style is defined there, use it; don't reinvent.src/routes/__root.tsxowns all chrome — header, nav, HTML shell. Child routes render inside<Outlet />. Never regenerate nav.- This is Tailwind v3, not v4. There's a
tailwind.config.ts. CSS entry uses@import 'tailwindcss/base'. Do not apply v4@theme/ CSS-first patterns here. - System fonts only. Never add Google Fonts, Fontsource, or web-font CSS. Display = body = system stack.
- No component libraries. No shadcn, Radix, Headless UI, or Motion. Plain React + Tailwind utility classes + the named component classes in
app.css.
The palette (memorize)
| Name | Value | Use |
|---|---|---|
| Primary blue | rgb(70, 110, 170) / #466eaa |
Post titles, bio banner bg, header border |
| Link blue | rgb(30, 70, 140) / #1e468c |
Body links (bold, no underline until hover) |
| Text | rgb(0, 0, 0) |
Body, H1 (in-content), site title |
| Muted | rgb(102, 102, 102) / #666 |
Dates, H2/H3 in post content |
| Footnote | rgb(170, 170, 170) / #aaa |
Nav links, post-footnote (italic date under title) |
| Border | rgb(222, 222, 222) / #dedede |
Tables, code blocks, pull-quote, post-footer hairline |
| Surface | rgb(249, 249, 249) / #f9f9f9 |
Code blocks, pull-quote, table headers |
| Bg | #fff |
Page |
No other colors. No dark mode. No Tailwind color-scale classes in new work (text-emerald-400, bg-zinc-700) — legacy posts/components have them and are being drifted back to the palette over time.
Type, layout, motion (one-liners)
- Type: system stack (
system, -apple-system, system-ui, 'Helvetica Neue', 'Lucida Grande', sans-serif), body 18px / line-height 28px. Monospace:'Courier New', monospaceat 16px. - Layout: 800px max-width container (
.container), 12px main-section padding. Tight vertical rhythm: paragraph mb 20px, heading mb 10–14px, code/pre margin 16px, pull-quote margin 12px, post-list items mb 8px. The old universal 30px block-margin rule is gone — seelayout.mdfor the current scale. - Motion: none. Links change text-decoration on hover. That is the entire motion vocabulary.
Before you touch anything
- Read the relevant reference below.
- Prefer existing named classes (
.bio-highlight,.post-list,.post-item,.post-date,.site-header,.site-nav,.blog-post,.post-title,.post-permalink,.post-footnote,.post-content,.pull-quote) over new Tailwind utilities. - If a new color, size, or spacing is truly needed, add it to
src/styles/app.css— not inline — and updatedesign.md. - Never touch the
$slugroute'sbeforeLoaddot-rejection logic (it protects/rss.xml,/favicon.ico, etc.).
References
- colors — exact values, where each is used, anti-patterns
- typography — font stack, sizes, headings hierarchy, meta/date style
- layout — 800px container, header, spacing, responsive rules
- components — header, bio-highlight, post-list, blog-post, post-content, static Mermaid figures, ExperienceCard drift
- blog-mdx — MDX frontmatter shape, post location, RSS sync, Mermaid usage
- blog-prose — voice, tone, markdown-usage standards, essay-structure archetypes for posts
- routing-and-chrome —
__root.tsxrules,$slugcatch-all, loader serialization - accessibility — focus ring, semantic HTML, WCAG AA contrast
Validation checklist
Before calling frontend work on wcygan.net done:
- No new hex colors outside the palette above (check
design.md/app.css) - No Google Font /
@import url(fonts.googleapis…)/ Fontsource added -
__root.tsxheader/nav not duplicated in child routes - New route renders inside
<Outlet />, usescreateFileRoute - MDX posts have
title,date,description,tagsfrontmatter - Loaders return serializable data only (no React components from loaders)
- No
ref.current.innerHTML— usedangerouslySetInnerHTMLvia state - Mermaid imported dynamically (
import('mermaid')), never top-level -
deno task pre-commitpasses (format + typecheck)
External canonical docs
- Project design spec:
/Users/wcygan/Development/wcygan.net/design.md - Global stylesheet:
/Users/wcygan/Development/wcygan.net/src/styles/app.css - Project CLAUDE.md:
/Users/wcygan/Development/wcygan.net/CLAUDE.md - TanStack Start: https://tanstack.com/start/latest/docs/framework/react/overview
- Tailwind v3 Typography plugin: https://tailwindcss.com/docs/typography-plugin
Complements
claude-code-best-practices— skill/hook authoring, always co-presenttanstack-start— general framework reference (routing, loaders, server fns)tailwind— general Tailwind utility reference (but confirm v3 vs v4 before applying)