DESIGN.md · Analysis
Andreas Osberghaus
osberghaus.io · 27 Jul 2026 · 47 colors · Source Serif 4, Source Sans 3
Andreas Osberghaus
Personal portfolio for a Bitcoin and Cardano developer. Minimal, monochromatic design with Bitcoin orange accent; supports light and dark modes.
Colors
Typography
- display
- fontFamily: Source Serif 4 · fontSize: 56px · fontWeight: 500 · lineHeight: 62px · letterSpacing: -0.01em
- headline-lg
- fontFamily: Source Serif 4 · fontSize: 45.6px · fontWeight: 500 · lineHeight: 51px · letterSpacing: -0.01em
- headline-md
- fontFamily: Source Serif 4 · fontSize: 32px · fontWeight: 500 · lineHeight: 40px · letterSpacing: -0.005em
- title-lg
- fontFamily: Source Sans 3 · fontSize: 20px · fontWeight: 600 · lineHeight: 28px · letterSpacing: 0.01em
- body-lg
- fontFamily: Source Sans 3 · fontSize: 17px · fontWeight: 400 · lineHeight: 27px · letterSpacing: 0.005em
- body-md
- fontFamily: Source Sans 3 · fontSize: 16px · fontWeight: 400 · lineHeight: 24px · letterSpacing: 0.005em
- label-md
- fontFamily: Source Sans 3 · fontSize: 14px · fontWeight: 600 · lineHeight: 20px · letterSpacing: 0.01em
- label-sm
- fontFamily: Source Sans 3 · fontSize: 12px · fontWeight: 500 · lineHeight: 16px · letterSpacing: 0.08em
- caption
- fontFamily: Source Sans 3 · fontSize: 11px · fontWeight: 400 · lineHeight: 16px · letterSpacing: 0.02em
- monospace
- fontFamily: ui-monospace, SF Mono, Cascadia Code, Source Code Pro, Menlo, Consolas, monospace · fontSize: 11px · fontWeight: 400 · lineHeight: 16px · letterSpacing: 0.01em
Design guidance
Overview
Andreas Osberghaus is a personal portfolio for a Bitcoin and Cardano developer, embodying a philosophy of **Architectural Minimalism**—where restraint and precision communicate expertise. The design employs a monochromatic light-mode foundation (#f7f5f2 background, #1a1a1a text) paired with a single, unmissable accent: Bitcoin orange (#f7931a). This accent appears on interactive elements (social links, focus states, hover effects) and serves as the visual signature of the brand. The aesthetic evokes clarity and technical rigor—every pixel intentional, every interaction responsive. The brand personality is direct, unadorned, and credible: a developer who builds infrastructure, not hype. Voice: precise, grounded, matter-of-fact. Example sentence: "Building AI agent infrastructure on Bitcoin and Cardano." The design respects system dark mode preferences, inverting the surface stack (#141311 background, #f0ede8 text) while maintaining the orange accent's prominence across both modes.
Colors
The color system operates on a principle of **monochromatic restraint with a single accent**. The primary surface palette consists of warm neutrals: light mode uses #f7f5f2 (surface), #1a1a1a (on-surface), and #5a5752 (on-surface-variant for muted text); dark mode inverts to #141311 (surface), #f0ede8 (on-surface), and #a39e96 (on-surface-variant). The accent color, #f7931a (Bitcoin orange), is reserved exclusively for interactive states: button hovers (background: rgba(247, 147, 26, 0.08)), link focus rings (box-shadow: 0 0 0 4px rgba(247, 147, 26, 0.55)), and icon highlights. Secondary grays (#8a8680, #6c757d, #505050) support UI chrome—borders, disabled states, and icon rests. The focus ring uses a computed color-mix: var(--focus-ring) = color-mix(in srgb, var(--accent) 55%, transparent
Typography
The type system pairs **Source Serif 4** for display hierarchy with **Source Sans 3** for body and UI text, creating a clear distinction between identity (serif headlines) and function (sans-serif prose). Display-level text (headline-lg: 45.6px, fontWeight 500, lineHeight 51px, letterSpacing -0.01em) uses the serif family to establish authority and personality; body text (body-lg: 17px, fontWeight 400, lineHeight 27px, letterSpacing 0.005em) uses sans-serif for legibility and approachability. Label text (label-md: 14px, fontWeight 600, letterSpacing 0.01em) applies tight tracking to UI controls, reinforcing their functional role. Monospace text (11px, letterSpacing 0.01em) is reserved for the Nostr public key, signaling technical content. All text rendering is optimized with font-feature-s
Layout
The layout follows a **centered, single-column grid** with a max-width of 576px (min(100%, 36rem)), ensuring the identity card remains readable on all viewports. The body uses display: grid; place-items: center; min-height: 100dvh to vertically and horizontally center the .identity container. Padding is set to 1.5rem (24px) on all sides, providing breathing room on mobile. Vertical rhythm is maintained through consistent gap and margin values: the name has margin-bottom: 0.35rem (5.6px), the subtitle 1.35rem (21.6px), the bio 1.25rem (20px), and the personal section 2.25rem (36px). The social nav uses gap: 0.5rem (8px) between icon buttons, while the motif (decorative dots) uses gap: 0.4rem (6.4px). This semantic spacing creates a visual hierarchy that guides the eye downward through the c
Elevation & Depth
Depth in this system is achieved through **subtle shadows and layered backgrounds** rather than dramatic z-index stacking. The base elevation uses no shadow; the standard card layer applies box-shadow: 0 3px 8px rgba(0, 0, 0, 0.15), creating a soft, diffuse shadow that suggests proximity without heaviness. Elevated surfaces (modals, dropdowns) use box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), a larger spread that conveys greater distance. Focus rings are implemented as double-line outlines: box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--focus-ring), where the inner 2px ring matches the backgro
Shapes
The shape language follows **Soft-Technical Minimalism**: rounded corners are minimal and purposeful, never decorative. Buttons and icon containers use border-radius: 999px (full pill shape) to signal clickability and approachability; this is applied to .social a (width: 44px, height: 44px) and button components. Cards and input fields use border-radius: 0.75rem (12px) for a subtle, modern softness that avoids the harshness of sharp corners while maintaining technical precision. The motif (decorative dots) uses border-radius: 50% to create perfect circles at 3.52px diameter. Dropdown panels an
Components
Action Elements Buttons and links are the primary interactive layer. Primary buttons use background: {colors.primary} (#f7931a), textColor: {colors.on-primary} (#1a1a1a), rounded: {rounded.full}, padding: 12px 24px, height: 44px. On hover, the background shifts to {colors.primary-fixed-dim} and the element lifts via transform: translateY(-1px). Focus states apply a double-line ring: box-shadow: 0 0 0 2px {colors.surface}, 0 0 0 4px {colors.primary}. Ghost buttons (secondary actions) use transparent background with textColor: {colors.on-surface}, and on hover, background becomes rgba(247, 147, 26, 0.08) with textColor shifting to {colors.primary}. Icon buttons (.social a) are 44px × 44px circles with border-radius: 999px, textColor: {colors.tertiary} (#3d3d3d) at rest, transitioning to
Do's and Don'ts
**Do**
- Do use the Bitcoin orange (#f7931a) accent exclusively on interactive elements—buttons, focus rings, hover states—to maintain visual hierarchy and guide user attention.
- Do apply the double-line focus ring (0 0 0 2px background, 0 0 0 4px accent) consistently across all interactive elements to meet WCAG AAA contrast and accessibility standards.
- Do respect the system color-scheme preference and provide both light (#f7f5f2) and dark (#141311) mode surfaces with matching accent prominence.
- Do use Source Serif 4 for headlines and identity text to establish authority; reserve Source Sans 3 for body and UI to maintain legibility and functional clarity.
- Do animate all state transitions (hover, focus, active) over 180ms ease to create a cohesive, responsive feel without feeling sluggish or jarring.
- Do maintain vertical rhythm by using semantic spacing tokens (sm: 12px, md: 24px, lg: 40px) for consistent gaps between sections and components.
**Don't**
- Don't use the accent color (#f7931a) on non-interactive elements or as a background fill; it must remain reserved for CTAs and focus states to avoid diluting its signal.
- Don't apply shadows heavier than 0 8px 24px rgba(0, 0, 0, 0.12) or use drop-shadow filters; keep elevation subtle and diffuse to maintain the minimalist aesthetic.
- Don't mix serif and sans-serif within a single text block; use Source Serif 4 for display and Source Sans 3 for body, never the reverse.
- Don't disable transitions or animations entirely in the default state; instead, respect prefers-reduced-motion: reduce by reducing transition-duration to 0.01ms and transition-delay to 0ms.
- Don't use border-radius values other than the defined scale (0.25rem, 0.5rem, 0.75rem, 1rem, 1.5rem, 999px); arbitrary radii break the technical precision of the system.
- Don't apply color-mix or computed colors directly in component styles; always reference CSS custom properties (--accent, --focus-ring) or token references ({colors.primary}) to maintain consistency across light and dark modes.
Edit, then copy or download.