Design System
The visual and interaction foundation of fred6.nl, tokens, components, and the decisions behind them.
Clients see how decisions get made, not just what they look like. AI agents get a structured map of every token and component in the system.
Why this system
Decisions
Every design choice is a trade-off. These are the six that define fred6.nl's system character, the reasoning behind each one matters as much as the choice itself.
- 01
Amber accent only, no blue tones
Contemporary, warm, unexpected in tech. Blue is the default palette of every SaaS product; amber creates immediate distinctiveness. A single accent hue enforces discipline, there is no second colour to reach for.
- 02
Light-first with manual dark toggle
Portfolio work shows best on light. Dark mode is a user preference, not a default. The toggle is persistent via
localStorage, but the initial experience is the light mode, the context in which the visual work was created. - 03
Tags are non-interactive labels
At 5–10 projects, filtering adds complexity without user value. The cognitive cost of a filter UI, learning the interaction, resetting state, recovering from empty results, outweighs any benefit at this scale. If the portfolio grows to 20+ projects, a dedicated filter row above the grid is the right pattern. Until then, scrolling is the interface.
- 04
Geist typeface
Tech-forward, free, purpose-built for screens by Vercel. It reads with authority at large display sizes and stays legible at caption scale. Self-hosted as
woff2, no Google Fonts dependency, no external DNS lookup on load. - 05
CSS custom properties for all tokens
No JS token files, no build-time transforms, no runtime overhead. Tokens live in
tokens.cssas native CSS custom properties, consumed directly in component<style>blocks. The browser handles dark mode viadata-themeattribute overrides on the<html>element. - 06
cursor: default on non-interactive pill elements
An explicit honesty signal. A pointer cursor on a non-clickable element is a broken promise, it invites a click that goes nowhere. Tags declare their non-interactive nature at the cursor level, before the user commits to an interaction that will not happen.
Foundations
Color
The palette is deliberately restrained. A single warm accent, amber, sits against a cool-grey neutral scale. No blue tones appear anywhere in the system; this is intentional (see Decisions). Semantic tokens alias the raw scale so components never reach for primitive values directly.
Neutral scale
--color-neutral-0 hsl(0 0% 100%) --color-neutral-50 hsl(220 14% 96%) --color-neutral-100 hsl(220 13% 91%) --color-neutral-200 hsl(220 11% 80%) --color-neutral-400 hsl(220 9% 55%) --color-neutral-600 hsl(220 10% 35%) --color-neutral-800 hsl(220 12% 18%) --color-neutral-900 hsl(220 14% 10%) --color-neutral-950 hsl(220 16% 6%) Accent, amber Brand accent
The sole chromatic hue in the system. No blue tones are used, amber reads as warm, contemporary, and unexpected in a tech context.
--color-accent hsl(45 48% 37%) --color-accent-light hsl(45 48% 50%) --color-accent-subtle hsl(45 48% 37% / 0.15) --color-accent-fg hsl(45 48% 36%) 4.67:1 on white Semantic tokens
Components consume semantic tokens, never raw primitives. These aliases flip
automatically between light and dark mode via data-theme.
--color-surface Page background neutral-0 / neutral-950 --color-surface-raised Cards, code chips, inputs neutral-50 / neutral-900 --color-surface-glass Frosted nav, glass panels white/0.7 · dark/0.75 --color-border Dividers, input outlines neutral-100 / neutral-800 --color-text Body copy, headings neutral-900 / neutral-50 --color-text-secondary Captions, nav links (idle) neutral-400 (both modes) Foundations
Typography
Geist, purpose-built for screens by Vercel, released as open source. All sizes
are fluid clamp() values that scale smoothly between
mobile and desktop viewports without breakpoint jumps.
Type scale
--text-xs clamp(0.75rem, 0.7rem + 0.25vw, 0.8125rem) The quick brown fox --text-sm clamp(0.875rem, 0.8rem + 0.35vw, 0.9375rem) The quick brown fox --text-base clamp(1rem, 0.95rem + 0.25vw, 1.0625rem) The quick brown fox --text-lg clamp(1.125rem, 1rem + 0.65vw, 1.25rem) The quick brown fox --text-xl clamp(1.25rem, 1.1rem + 0.85vw, 1.5rem) The quick brown fox --text-2xl clamp(1.5rem, 1.25rem + 1.3vw, 2rem) The quick brown fox --text-3xl clamp(2rem, 1.5rem + 2.5vw, 3rem) The quick fox --text-display clamp(3rem, 2rem + 5vw, 5rem) The quick fox Font weights
--weight-regular 400 --weight-medium 500 --weight-semibold 600 --weight-bold 700 Line heights
--leading-tight · 1.1 Design systems are living artifacts. They breathe with the product they serve.
--leading-snug · 1.3 Design systems are living artifacts. They breathe with the product they serve.
--leading-normal · 1.5 Design systems are living artifacts. They breathe with the product they serve.
--leading-relaxed · 1.7 Design systems are living artifacts. They breathe with the product they serve.
Foundations
Spacing
A fixed 4px base unit scale. The visual ruler below renders each token as a bar whose width matches the actual token value, making the relationships between steps immediately legible.
--space-1 0.25rem --space-2 0.5rem --space-3 0.75rem --space-4 1rem --space-5 1.25rem --space-6 1.5rem --space-8 2rem --space-10 2.5rem --space-12 3rem --space-16 4rem --space-20 5rem --space-24 6rem --space-32 8rem Foundations
Motion
Three intentional easing curves and three duration tokens. Hover each demo box to see the easing in action, the box slides 60px right and returns. All animation in the system is CSS-only, no JavaScript motion libraries.
Easing curves
--ease-out-expo cubic-bezier(0.16, 1, 0.3, 1) UI transitions, nav, buttons --ease-spring cubic-bezier(0.34, 1.56, 0.64, 1) Playful moments, icons, accents Duration tokens
--duration-fast 120ms, hover states, focus rings --duration-base 220ms, most UI transitions --duration-slow 400ms, page-level animations In practice
Composition
Tokens don't live in isolation. This is what the system looks like when everything comes together, real components, real tokens, no mocks.
Web Platform Design
Bringing structure and consistency to a fragmented digital ecosystem.
Web Platform Design
Bringing structure and consistency to a fragmented digital ecosystem.
Components
Button
Three variants covering the full interaction spectrum. Primary draws attention with the amber accent fill. Ghost holds space without competing. Text is for in-line or low-emphasis navigation cues.
Component API
label string required Any string variant string 'primary' 'primary' | 'ghost' | 'text' href string — Renders as <a> when present type string 'button' 'button' | 'submit' | 'reset' Light context
Dark context
Components
Tag
Non-interactive label pills used to classify project work. Tags are purely presentational, they communicate metadata, not actions.
Accessibility decisions
- cursor: default, explicit honesty signal. The element is not interactive; it must not look like it is.
- role="list" wrapper, when multiple tags are rendered together, the parent should carry
role="list"so screen readers announce the count. - Contrast ratio 4.67:1,
--color-accent-fg(hsl 45 48% 36%) against white. Passes WCAG AA (4.5:1). Dark mode uses hsl(45 55% 68%) for sufficient contrast on dark surfaces. - user-select: none, prevents accidental text selection on non-text content.
Component API
label string required Any string size string 'md' 'md' | 'sm' Light context
Dark context
Components
FrostedPanel
A backdrop-blur glass surface. Used sparingly, the nav gains this treatment after 16px of scroll, and intentional "glass moment" layouts can use it for visual depth. Overusing frosted glass flattens the effect; restraint is the rule.
Component API
class string — Forwarded to wrapper div for sizing/spacing
Content is passed via <slot />. The component owns only
the glass surface, sizing, padding, and layout are always the consumer's responsibility.
In use
Glass surface
Backdrop blur of 12px (--glass-blur). Background
opacity adapts via --glass-bg, 72% white on light,
72% dark on dark. Border uses --glass-border.
Seen enough to want to talk?
Get in touch