a951c00e35
- Killed 16 em-dashes (Claude fingerprint, 15.9/1000 words -> 0) - Replaced all clause-dash-elaboration patterns with periods, colons, restructuring - Removed 'The One-Sentence Version' section (restated the intro, voice anti-pattern) - Broke tricolon at lines 56-58 (too-clean parallel structure) - Collapsed 'How to Actually Help' listicle into connective prose - Added receipt link for ~100x inference cost claim - Heading dashes replaced with colons (Tradesman Analogy, Excellence vs Functional) New tooling: - scripts/lint-voice.sh: mechanical anti-slop linter (em-dashes, trigger words, hedging, filler, receipts, sentence uniformity) - .amplifier/skills/voice-check/SKILL.md: LLM-as-judge voice authenticity check (8 dimensions against VOICE.md profile) - .amplifier/AGENTS.md: standing rule requiring both checks before any publish 🤖 Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
264 lines
14 KiB
Markdown
264 lines
14 KiB
Markdown
---
|
|
name: Crash Test Dev
|
|
description: >
|
|
A personal technical publishing site. Workbench aesthetic --
|
|
warm, grounded, un-digital. Paper, ink, wood, stone, iron.
|
|
Three typographic voices: serif for prose, sans for structure,
|
|
mono for evidence.
|
|
|
|
colors:
|
|
primary: "#2B2421"
|
|
secondary: "#6B5F55"
|
|
tertiary: "#A0522D"
|
|
neutral: "#F5F0E8"
|
|
on-primary: "#F5F0E8"
|
|
on-tertiary: "#FEFCF7"
|
|
surface: "#FEFCF7"
|
|
surface-code: "#EEEAE2"
|
|
surface-inset: "#E8E3DA"
|
|
accent-hover: "#8B4726"
|
|
accent-secondary: "#7D6C2F"
|
|
accent-secondary-hover: "#6B5C28"
|
|
code-text: "#3D342E"
|
|
border-subtle: "#DDD7CD"
|
|
border-default: "#C2BAA9"
|
|
border-strong: "#8E857A"
|
|
success-bg: "#E8EDDF"
|
|
success-text: "#4A5E3A"
|
|
warning-bg: "#F2E8D0"
|
|
warning-text: "#7A5C1F"
|
|
error-bg: "#F2DED6"
|
|
error-text: "#8B3A2A"
|
|
|
|
typography:
|
|
h1:
|
|
fontFamily: Inter
|
|
fontSize: 2.75rem
|
|
fontWeight: 700
|
|
lineHeight: 1.15
|
|
letterSpacing: -0.02em
|
|
h2:
|
|
fontFamily: Inter
|
|
fontSize: 2.25rem
|
|
fontWeight: 600
|
|
lineHeight: 1.25
|
|
letterSpacing: -0.015em
|
|
h3:
|
|
fontFamily: Inter
|
|
fontSize: 1.75rem
|
|
fontWeight: 600
|
|
lineHeight: 1.3
|
|
letterSpacing: -0.01em
|
|
h4:
|
|
fontFamily: Inter
|
|
fontSize: 1.375rem
|
|
fontWeight: 600
|
|
lineHeight: 1.35
|
|
letterSpacing: -0.005em
|
|
body-md:
|
|
fontFamily: Source Serif 4
|
|
fontSize: 1.125rem
|
|
fontWeight: 400
|
|
lineHeight: 1.7
|
|
body-sm:
|
|
fontFamily: Source Serif 4
|
|
fontSize: 0.875rem
|
|
fontWeight: 400
|
|
lineHeight: 1.6
|
|
letterSpacing: 0.005em
|
|
blockquote:
|
|
fontFamily: Source Serif 4
|
|
fontSize: 1.25rem
|
|
fontWeight: 400
|
|
lineHeight: 1.6
|
|
caption:
|
|
fontFamily: Inter
|
|
fontSize: 0.875rem
|
|
fontWeight: 500
|
|
lineHeight: 1.5
|
|
letterSpacing: 0.01em
|
|
label:
|
|
fontFamily: Inter
|
|
fontSize: 0.75rem
|
|
fontWeight: 600
|
|
lineHeight: 1.5
|
|
letterSpacing: 0.05em
|
|
code-inline:
|
|
fontFamily: JetBrains Mono
|
|
fontSize: 0.9em
|
|
fontWeight: 400
|
|
code-block:
|
|
fontFamily: JetBrains Mono
|
|
fontSize: 1rem
|
|
fontWeight: 400
|
|
lineHeight: 1.6
|
|
|
|
rounded:
|
|
sm: 2px
|
|
md: 4px
|
|
lg: 6px
|
|
xl: 8px
|
|
full: 9999px
|
|
|
|
spacing:
|
|
xs: 4px
|
|
sm: 8px
|
|
md: 16px
|
|
lg: 24px
|
|
xl: 32px
|
|
2xl: 40px
|
|
3xl: 48px
|
|
4xl: 64px
|
|
|
|
components:
|
|
article-card:
|
|
backgroundColor: "{colors.surface}"
|
|
textColor: "{colors.primary}"
|
|
rounded: "{rounded.lg}"
|
|
padding: 24px
|
|
article-card-hover:
|
|
backgroundColor: "{colors.surface}"
|
|
textColor: "{colors.tertiary}"
|
|
code-block:
|
|
backgroundColor: "{colors.surface-code}"
|
|
textColor: "{colors.code-text}"
|
|
rounded: "{rounded.md}"
|
|
padding: 24px
|
|
callout-pattern:
|
|
backgroundColor: "{colors.surface-inset}"
|
|
textColor: "{colors.primary}"
|
|
rounded: "{rounded.lg}"
|
|
padding: 24px
|
|
callout-antipattern:
|
|
backgroundColor: "{colors.surface-inset}"
|
|
textColor: "{colors.primary}"
|
|
rounded: "{rounded.lg}"
|
|
padding: 24px
|
|
audio-player:
|
|
backgroundColor: "{colors.surface-inset}"
|
|
textColor: "{colors.secondary}"
|
|
rounded: "{rounded.full}"
|
|
padding: 16px
|
|
audio-player-expanded:
|
|
backgroundColor: "{colors.surface-inset}"
|
|
textColor: "{colors.secondary}"
|
|
rounded: "{rounded.lg}"
|
|
padding: 16px
|
|
nav-bar:
|
|
backgroundColor: "{colors.neutral}"
|
|
textColor: "{colors.secondary}"
|
|
---
|
|
|
|
## Overview
|
|
|
|
Crash Test Dev is a personal technical publishing site built on a single metaphor: **the workbench, not the gallery.** The design draws from a materials vocabulary of paper, ink, wood, stone, and iron -- surfaces that have been used, heated, cooled. Nothing gleams. Nothing floats. Every element earns its presence through function.
|
|
|
|
The aesthetic is quiet confidence with warmth. Warm off-white backgrounds like heavy unbleached paper stock. Brown-black text like good ink. A muted terracotta accent drawn from fired earth -- the site's only color with intent. Three typographic voices work together: a serif for prose (Ken's voice on the page), a sans for structure (headings, navigation, labels), and a monospace for evidence (code, proof, receipts).
|
|
|
|
The site serves a personal audience hierarchy: the author first (this is a reference for his own thinking), his children someday, peers in engineering second, and other travelers last. The craft level is high because craft is how you show respect for your own thinking -- not because someone is performing quality. If someone inspects the page and thinks "there's not much design here," the design succeeded.
|
|
|
|
This is not a corporate dev blog. Not a portfolio. Not a "personal brand." It's a thinking journal published with the care of a printed essay. The writing is the hero. The design gets out of the way and makes the reading experience exceptional.
|
|
|
|
## Colors
|
|
|
|
The palette is warm across all values. No blue-grays, no cool neutrals. The temperature comes from keeping red channel values higher than green and blue at every level of the scale, creating visual comfort even at strong contrast ratios.
|
|
|
|
- **Primary (#2B2421):** Brown-black ink. The warmth comes from RGB (43, 36, 33) -- red leads. Body text, headlines, anything that demands full attention. 13.44:1 contrast on the neutral surface (AAA).
|
|
- **Secondary (#6B5F55):** Warm stone gray. Metadata, captions, bylines, navigation links at rest. 5.46:1 on neutral (AA).
|
|
- **Tertiary (#A0522D):** Muted terracotta, CSS "sienna." The sole accent color -- literally fired earth. Links, emphasis, code block left-edge accents. 4.95:1 on neutral (AA). The hover state (#8B4726) darkens toward earth, not toward black.
|
|
- **Neutral (#F5F0E8):** Heavy unbleached paper stock. Page background. RGB (245, 240, 232) tapers R > G > B, placing the warmth in the red channel without becoming cream or beige.
|
|
- **Surface (#FEFCF7):** White card stock laid on the paper base. Reading areas, article cards.
|
|
- **Surface-code (#EEEAE2):** Heavier paper weight. Code blocks. The material shift signals "different register."
|
|
- **Surface-inset (#E8E3DA):** Recessed surface for callouts, asides, and the audio player.
|
|
- **Accent-secondary (#7D6C2F):** Tarnished brass. The green-gold of aged copper alloy. For tips, special highlights.
|
|
|
|
State colors stay within the warm palette: sage green for success (#4A5E3A on #E8EDDF), warm amber for warnings (#7A5C1F on #F2E8D0), deeper terracotta for errors (#8B3A2A on #F2DED6). No saturated primaries anywhere.
|
|
|
|
## Typography
|
|
|
|
Three voices, three jobs. The reader always knows which voice is speaking.
|
|
|
|
**Source Serif 4** is the prose voice -- Ken's voice on the page. A transitional serif at 18px (1.125rem) with 1.7 line-height, generous enough for dense technical narrative. Weight 400 for body, 600 for inline emphasis. The serif signals "this is meant to be read at the pace of thought." It carries the authority of published writing without the stiffness of academic text. Blockquotes step up to 20px italic -- a different register, clearly quoted words.
|
|
|
|
**Inter** is the structure voice. Headings, UI labels, metadata, timestamps, navigation. It organizes without competing with the prose. Semi-bold (600) for headings creates contrast with the lighter serif body without shouting. Negative letter-spacing at display sizes (-0.02em for h1, tapering to -0.005em for h4) because Inter at large sizes needs tightening to feel intentional.
|
|
|
|
**JetBrains Mono** is the evidence voice. Code blocks, terminal output, file paths, inline code. This is where receipts are shown. Slightly smaller than prose (0.9em inline, 1rem in blocks) with 1.6 line-height. Clear character differentiation. Factual, verifiable.
|
|
|
|
The type scale uses a Major Third ratio (1.25) from the 18px base: 12, 14, 18, 22, 28, 36, 44px. Conservative -- hierarchy comes from weight and family contrast, not dramatic size jumps.
|
|
|
|
A system-wide label treatment (12px Inter semibold, uppercase, 0.05em tracking) appears identically on article cards, callout headers, and post headers. Recognize it once, understand it everywhere.
|
|
|
|
## Layout
|
|
|
|
The page breathes like a well-set book with one key deviation: code breaks the column.
|
|
|
|
Prose lives in a reading column at 720px (45rem, approximately 65 characters per line at 18px serif). This is the typographic sweet spot for sustained reading. Code blocks break wider to 840px (52.5rem), creating a narrow-wide-narrow rhythm as you scroll. The width shift signals the register change from narrative to evidence -- your eye physically moves to a wider surface when the voice changes from serif prose to mono proof.
|
|
|
|
Vertical rhythm follows the content's natural structure. H2 headings get 64px above them -- a full breath between sections, because section breaks are chapter breaks. H2-to-content gets just 16px -- the heading belongs to what follows. H3 gets 40px above, H4 gets 32px. Paragraph spacing is 24px. Code blocks get 40px above and below -- exhibited artifacts, not inline interruptions.
|
|
|
|
The outer container is 1100px. Side gutters are 24px minimum. On narrow viewports, the prose column narrows gracefully. No breakpoint-driven layout shifts -- it's a single column that adapts.
|
|
|
|
Spacing follows an 8px base grid: 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96px.
|
|
|
|
## Elevation & Depth
|
|
|
|
Nothing floats. The maximum depth in the system is a hovered article card.
|
|
|
|
The entire depth vocabulary: page background (no shadow, neutral surface), cards at rest (shadow-sm: barely perceptible desk shadow), cards on hover (shadow-md: the maximum), and inset surfaces (no shadow, background shift only). That's it.
|
|
|
|
Shadows use warm-toned RGBA derived from the primary ink color: `rgba(43, 36, 33, 0.04)` for sm, `rgba(43, 36, 33, 0.06)` for md. No dramatic elevation. No layered depth system. If something casts a shadow, it's the small soft shadow of a card sitting on a desk.
|
|
|
|
Code blocks and callouts feel inset -- a background shift plus a 3px left-edge accent line in terracotta. The accent line is a consistent grammar: "pay attention, this is a different voice." Different material embedded in the page, not floating above it.
|
|
|
|
## Shapes
|
|
|
|
Workshop surfaces have worn edges, not machined radii. Four meaningful stops:
|
|
|
|
- **sm (2px):** Inline code spans, small tags and badges. Barely softened.
|
|
- **md (4px):** Code blocks, buttons, small interactive elements. Just enough to not feel sharp.
|
|
- **lg (6px):** Article cards, callout boxes. Slightly more wear.
|
|
- **xl (8px):** Larger panels if ever needed. Still not "round."
|
|
- **full (9999px):** Pills only -- the audio player collapsed state, avatars.
|
|
|
|
No radius exceeds 8px except full. Nothing on this site should look like a mobile app button or a glassmorphism card.
|
|
|
|
## Components
|
|
|
|
Six core components define the visual vocabulary.
|
|
|
|
**article-card** -- An index card laid on the desk. White surface (`{colors.surface}`) with the system's only use of shadow (sm at rest, md on hover). Content type badge in terracotta uppercase label, title in 28px Inter semibold, summary in serif, date in tertiary. The entire card is a single link -- touch target is the full surface. On hover, the shadow deepens and the title shifts to terracotta.
|
|
|
|
**code-block** -- The evidence container. Breaks wider than prose (840px vs 720px). Heavier paper background (`{colors.surface-code}`) with a 3px terracotta left border accent. No shadow -- it's inset. Optional filename label in 12px Inter at top-right. Syntax highlighting stays warm: terracotta for keywords, tarnished brass for strings, no neon anywhere. Warm-styled scrollbar for horizontal overflow.
|
|
|
|
**audio-player** -- Starts as a pill (offer, not demand): play icon, "Listen," duration. Expands to full transport controls within the prose column: play/pause, progress bar with terracotta fill, time in mono (because time is a fact), speed selector cycling 1x through 2x. The one layout animation in the system (250ms expand/collapse) is justified because the shape change communicates a mode shift.
|
|
|
|
**callout** -- A sticky note on the workbench. Inset surface with a 3px left accent, color varying by type: terracotta for Pattern, clay-red for Anti-pattern, amber for Warning, tarnished brass for Tip, neutral for Note. Same uppercase label treatment as article cards. Body in serif at full reading weight. Static -- callouts are read, not clicked.
|
|
|
|
**post-header** -- Typography IS the hero. Centered stack on the base surface: content type badge, title at 44px Inter bold, meta line (date and reading time in tertiary), optional audio pill. No container, no border, no shadow. 64px breathing room above and below. Title steps down the type scale on narrow viewports (44 to 36 to 28px) but the hierarchy holds.
|
|
|
|
**nav-bar** -- The quietest component. Same surface as the page (no separate background). Site name at 18px Inter semibold left, three content type links right (Posts, Patterns, Lessons). Active page gets a 2px terracotta underline offset 6px below. One subtle border-bottom score line. Static positioning because persistent nav steals reading space. No hamburger for three links.
|
|
|
|
## Do's and Don'ts
|
|
|
|
**Do** use serif (Source Serif 4) for all long-form prose. The serif is the primary voice.
|
|
|
|
**Do** use the terracotta accent (#A0522D) sparingly -- for links, emphasis, and left-edge accents on code blocks and callouts. It's the site's only intentional color.
|
|
|
|
**Do** let code blocks break wider than prose. The 720px-to-840px rhythm is the core visual pattern.
|
|
|
|
**Do** maintain the warm temperature across everything. Every surface, every text color, every border should feel warm. If a color has a blue or cool undertone, it doesn't belong here.
|
|
|
|
**Do** keep shadows minimal and warm-toned. shadow-md on a hovered card is the maximum depth anywhere.
|
|
|
|
**Don't** use dark mode, neon syntax highlighting, or saturated primary colors. Ken's work happens in daylight.
|
|
|
|
**Don't** add hero images, gradient banners, or decorative illustrations. The writing is the hero. Typography is the visual weight.
|
|
|
|
**Don't** use animation beyond color transitions (100ms) and the audio player expand (250ms). This is a reading site, not an app.
|
|
|
|
**Don't** add sidebar content, newsletter CTAs, social media icons, or "hire me" elements. This is a library, not a landing page.
|
|
|
|
**Don't** use glassmorphism, blur effects, or any visual treatment that will look dated in two years. Paper, ink, and careful spacing don't go out of style.
|
|
|
|
**Don't** underline links in body prose except on hover. The terracotta color already signals "this is a link." Underline appears on hover as confirmation, and as the active-state indicator in the nav.
|