jeen design system — v0.6.4
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.
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.
| Rule | Guidance | Example |
|---|---|---|
| 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 |
| Rule | Requirement | How 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 |
Space Grotesk
--font-display · Display, Headings
DM Sans
--font-body · Body, UI text
JetBrains Mono
--font-mono · Code, system data
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.
8px base grid. All spacing values are multiples of 4px.
--bg-primary / #FAFAFA
Content sections
--bg-surface / #F5F5F0
Cards, raised elements
--bg-dark / #0A0A0A
Hero, footer, callouts
--bg-accent / #F3FE52
Sparingly — bold callout
--bg-accent-dim / #E8F23D
Hover / subtle accent
Four semantic border tokens cover all surfaces. Pick by surface context — never use raw color values for borders.
| Surface | Token to use | Never 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 |
| Rule | Guidance |
|---|---|
| Primary system | Lucide Icons (CDN) — 2px stroke, 24px grid, SVG only |
| Style | Outline/stroke icons — matches the doodle line-art aesthetic |
| Sizes | 16px (dense UI) · 20px (default) · 24px (prominent) |
| Color | Inherits from text color; yellow used for accent icons |
| Custom doodle icons | Hand-drawn SVGs for signature brand moments (Ask, dashboard) |
| Prohibited | No emoji as UI icons · No PNG · No filled icons |
| SVG in code | Use inline SVG for currentColor inheritance. Import with ?url only for decorative images. |