← Jeen.work / Design System
Foundations Components Dashboard

jeen design system — v0.6.4

Foundations

01

Project context

Jeen's portfolio is a living design system — structured data made visible. Instead of a static case-study portfolio, it showcases design thinking through the system itself.

Portfolio website

Main public-facing site — showcases work, thinking, and the design system itself.

Public dashboard

Visual display of the design system as structured data — this page.

"Ask my system" interface

AI chat for querying the design system. Ask anything about how I work.

02

Design principles

Voice & Tone
✍️

First-person, personal

Jeen writes as "I" — direct, warm, specific. Active voice always: "I built" not "was built by".

💬

Conversational but smart

Talks like a thoughtful designer, not a corporate brand. No "leverage", "synergy", or "solutions".

🎯

Professional but fun

Wit and personality come through. This isn't stiff. Building-in-public energy.

🔍

Explains why, not just what

Curious. Designer talking to designers + collaborators. Tells the story behind decisions.

Content rules
RuleGuidanceExample
Casing — headlines Sentence case (not Title Case or ALL CAPS) — feels conversational "My portfolio is a design system"
Casing — labels/UI Sentence case for most; occasional ALL CAPS for metadata/tags PROJECT · TALK · FEATURED
CTAs Short, punchy "See the system" / "Ask it anything"
Emoji Sparingly — never as UI icon replacement; occasional in body copy for personality ✓ A 🎉 at a milestone    ✗ 🐱 as card decoration
Accessibility rules
RuleRequirementHow to check
Normal text contrast Minimum 4.5:1 contrast ratio against its surface background (WCAG AA) Use WebAIM Contrast Checker — input text color + surface color
Large text contrast Minimum 3:1 for text ≥ 18pt (24px) regular or ≥ 14pt (18.67px) bold Same tool — check both text color and background
Text on dark (#0A0A0A) Use only: gray-300 (~9:1) · gray-400 (~5:1) · white (~19:1) · yellow (~17.6:1) Never use gray-500, gray-700, gray-900 — all fail AA on black
Text on white (#FFFFFF / #FAFAFA) Use gray-700 (~9:1) or darker. Avoid gray-400 (~2.6:1) and gray-500 (~5.1:1 — borderline, avoid for small text) Check before using any gray lighter than gray-700 on light surfaces
Text on yellow (#F3FE52) Use only black (#0A0A0A) — yellow is very light (L≈0.93), only black achieves >4.5:1 Never use white or any gray on yellow — all fail
Focus rings Yellow focus ring 2px solid #F3FE52 must appear on a dark or mid-tone background to be visible Test keyboard navigation — focus outline must be clearly visible against adjacent colours
Safe tokens on dark (#0A0A0A)
Primary text --fg-on-dark-primary ~19:1 ✓
Secondary text --fg-on-dark-secondary ~9:1 ✓
Labels / captions --fg-on-dark-label ~5:1 ✓
Accent text --fg-on-dark-accent ~17.6:1 ✓
03

Color system

Base colors
--color-black #0A0A0A Text, borders, backgrounds
--color-white #FAFAFA Light bg, cards, text on dark
--color-yellow #F3FE52 Accent, CTA, hover states
--color-yellow-dim #E8F23D Pressed/darker yellow
--color-yellow-pale #FAFEC7 Tag backgrounds
Gray scale
gray-50#F9F9F4
gray-100#F5F5F0Surface bg
gray-200#E8E8E0Borders (light bg)
gray-300#C8C8C0Text on dark
gray-400#9A9A90Captions, labels
gray-500#6A6A60
gray-700#3A3A35Body text on light bg
gray-900#1A1A15Deep dark surface
Status colors
--color-success#3DFE87Live indicator, success state
--color-warning#F3FE52Warning (= yellow)
--color-error#FF4444Error state, coming soon badge
--color-info#52B8FEInformational
Semantic tokens
--bg-primary#FAFAFAMain page background
--bg-dark#0A0A0AHero, footer, dark sections
--bg-accent#F3FE52Yellow feature callout
--bg-accent-dim#E8F23DIcon button hover / dim accent
--bg-surface#F5F5F0Card surface, section bg
--bg-surface-raised#FFFFFFElevated cards
--bg-inverse#1A1A15Inverse / deep dark
--fg-primary#0A0A0APrimary text
--fg-secondary#3A3A35Body text
--fg-tertiary#9A9A90Captions, labels
--fg-inverse#FAFAFAText on dark bg
--fg-accent#0A0A0AText ON yellow bg
--fg-on-dark-accent#F3FE52Yellow on dark
04

Typography

Font families

Space Grotesk

--font-display · Display, Headings

DM Sans

--font-body · Body, UI text

JetBrains Mono

--font-mono · Code, system data

Type scale
Display
72px / 700
Space Grotesk
--text-7xl
Hello, I'm Jeen
H1
48px / 700
Space Grotesk
--text-5xl
Agentic design system
H2
36px / 600
Space Grotesk
--text-4xl
Selected work
H3
24px / 600
Space Grotesk
--text-2xl
Ask my system
Body
16px / 400
DM Sans
--text-base
Instead of a traditional portfolio, this is a living system where design exists as structured data that can be queried and explored.
Body-lg
18px / 400
DM Sans
--text-lg
Designer, builder, thinker.
Label
14px / 500
DM Sans · UPPER
--text-sm
Category · Tag · Status
Mono
14px / 400
JetBrains Mono
--text-sm
system.query("What's Jeen's design process?")
Diary / article page — additional tokens

These styles are applied in article markdown content (slug.astro):

Inline code

const system = new DesignSystem()

bg: #0A0A0A · color: #FAFAFA · border-radius: 4px

Horizontal rule


border-top: 2px solid gray-300 (#C8C8C0) · width: 60px

Prose links

Prose links use the global <a> box-shadow underline pattern — see Components → Link for all variants.

05

Spacing

8px base grid. All spacing values are multiples of 4px.

--space-1  4px
--space-2  8px
--space-3  12px
--space-4  16px
--space-5  20px
--space-6  24px
--space-8  32px
--space-10  40px
--space-12  48px
--space-16  64px
--space-20  80px — section-padding-y
--space-24  96px
--space-32  128px
06

Shadows & border radii

Hard offset shadows — doodle aesthetic
--shadow-xs
1px 1px
--shadow-sm
2px 2px
--shadow-md
3px 3px
--shadow-lg
5px 5px
--shadow-xl
8px 8px
shadow-soft
elevated
Border radii
--radius-none
0px
--radius-xs
4px
--radius-sm
6px
--radius-md
12px
--radius-lg
16px
--radius-xl
24px
--radius-full
9999px
Animation tokens
🌊
--ease-spring
cubic-bezier(0.34, 1.56, 0.64, 1) · Playful overshoot — card hover, button lift
--ease-out
cubic-bezier(0.22, 1, 0.36, 1) · Exits, link transitions
--ease-in-out
cubic-bezier(0.65, 0, 0.35, 1) · Balanced transitions
150ms
--duration-fast
Micro-interactions: link hovers, icon states
250ms
--duration-base
Card hover, button states
400ms
--duration-slow
Page transitions, larger reveals
07

Section backgrounds

Light

--bg-primary / #FAFAFA
Content sections

Surface

--bg-surface / #F5F5F0
Cards, raised elements

Dark

--bg-dark / #0A0A0A
Hero, footer, callouts

Accent

--bg-accent / #F3FE52
Sparingly — bold callout

Accent dim

--bg-accent-dim / #E8F23D
Hover / subtle accent

08

Borders

Border tokens

Four semantic border tokens cover all surfaces. Pick by surface context — never use raw color values for borders.

--border-primary 1.5px solid #0A0A0A Default border — cards, inputs, buttons on light bg
--border-subtle 1px solid #E8E8E0 Dividers on light surfaces — table rows, section separators
--border-on-dark 1px solid #3A3A35 Dividers on dark surfaces (--bg-dark) — work rows, dark cards
--border-accent 2px solid #F3FE52 Accent highlights — featured badges, active states, callouts
Usage rules
SurfaceToken to useNever use
Light bg (--bg-primary, --bg-surface) --border-primary or --border-subtle Raw hex · --color-gray-*
Dark bg (--bg-dark) --border-on-dark or --border-accent --border-primary · --border-subtle · --color-gray-900 (invisible)
Accent / CTA element --border-accent Any other border on yellow — primary is fine too
09

Iconography

RuleGuidance
Primary systemLucide Icons (CDN) — 2px stroke, 24px grid, SVG only
StyleOutline/stroke icons — matches the doodle line-art aesthetic
Sizes16px (dense UI) · 20px (default) · 24px (prominent)
ColorInherits from text color; yellow used for accent icons
Custom doodle iconsHand-drawn SVGs for signature brand moments (Ask, dashboard)
ProhibitedNo emoji as UI icons · No PNG · No filled icons
SVG in codeUse inline SVG for currentColor inheritance. Import with ?url only for decorative images.