Design System

Visual tokens, typography, and component patterns for chris-tien.com

Color Palette

Backgrounds
#000
Page Background
#0a0a0a
TOC / Inset
#111
Card / Auth Gate
#1a1a1a
Dividers / Hover BG
#fff
Modal / Button Fill
Text
#fff
Primary
#ccc
Body Copy
#999
Breadcrumb Current
#888
Secondary / Hint
#777
Breadcrumb Link
#555
Muted / Subtitle
#666
Tertiary Text / Recent Desc
#444
Footer / Dim
Borders
#555
Search Underline
#333
Input Border
#3a3a3a
Breadcrumb Sep
#222
Hero Border
#1a1a1a
List Divider
Semantic
#f87171
Error / Destructive
#e5e5e5
Button Hover

Typography

Font stack: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif

5rem / 900
lh 1 / ls -0.04em
UPPERCASE
Gallery Display
1.8rem / 900
ls -0.03em
UPPERCASE
Tile Name
2.6rem / 700
lh 1.15 / ls -0.03em
Hero Text
2.5rem / 700
lh 1.15 / ls -0.03em
Page Heading
1.75rem / 700
lh 1.15
Legal / Changelog h1
1.4rem / 700
Modal Heading
1.2rem / 700
ls -0.01em / lh 1.3
Project Title
1.1rem / 400
Footer / Arrow
1.05rem / 400
lh 1.75
Bio body text — system sans-serif at comfortable reading size
1rem / 400
lh 1.6
Base body text, breadcrumbs, inputs, modal links
0.9rem / 400
lh 1.65 / color #888
Project descriptions and secondary body copy
0.85rem / 400
color #f87171
Error message text
0.8rem / 400
lh 1.3
Brand labels, small captions
0.75rem / 600
ls 0.08em / UPPERCASE
Section labels, project numbers
0.72rem / 400
monospace
Token values, code, meta labels

Buttons

Variant Background Border Radius Weight Padding
Primary #fff → #e5e5e5 2px solid #fff 999px (pill) 700 0.6rem 2rem
Secondary #000 → #1a1a1a 2px solid #fff 999px (pill) 400 0.6rem 2rem
Tertiary transparent none n/a 400 0 (icon + label)
Auth / Form #fff → #ddd none 8px 600 0.75rem (full width)

Form Elements

Incorrect password. Try again.
PropertyValue
Background#000
Border1px solid #333 → #fff on focus
Border radius8px
Padding0.75rem 1rem
Font size1rem
Transitionborder-color 0.2s

Components

Breadcrumb

Project Card

01
Project Title
Short description of the project — what it does and what tech it uses.

Modal (Quick Links)

Auth Gate

Chris Tien

Enter password to continue

Category Tile

Large clickable card used as a category entry point. Square corners, dark surface, background emoji at low opacity, white bottom-border animation on hover.

🎮
Games 21
Playable mini-projects and experimental mechanics.
PropertyValue
Background#0a0a0a
Border1px solid #1a1a1a → #333 on hover
Border radius0 (square — intentional gallery aesthetic)
Min height200px (desktop), 160px (mobile)
Bottom accent::after, height 2px, #fff, width 0 → 100% on hover (0.5s)
Iconposition: absolute top-right, opacity 0.06 → 0.18 + scale(1.1) on hover
Title1.8rem / 900 / uppercase / ls -0.03em
Description0.75rem / uppercase / ls 0.08em / color #888

Filter Pill

Sub-category filter tabs. Distinct from primary/secondary CTAs — lighter weight, 1px border, used for filtering project lists.

PropertyValue
Border1px solid #222 (inactive) / 1px solid #fff (active)
Border radius999px (pill)
Padding0.45rem 0.9rem
Font size0.85rem
Inactivecolor #555, bg transparent
Hovercolor #aaa, border #333
Activebg #fff, color #000, border #fff
Count label0.72rem, opacity 0.6 (0.5 when active)

Search Input — Underline Variant

Used on category landing pages. No background or box — bottom border only, uppercase text, brighter placeholder than the standard input.

PropertyValue
Borderbottom only: 1px solid #555 → #fff on focus
Backgroundnone (transparent)
Border radius0
Padding0.85rem 0.25rem
Font size1rem, uppercase, ls 0.05em
Placeholderrgba(255,255,255,0.3)
Icon color#888
Transitionborder-color 0.2s

Recent Card

Used on the projects hub to surface the 3 newest projects. Emoji thumbnail with grayscale filter (color on hover), optional "Newest" badge, title slide on hover.

Newest 🏰
Age of Conflict
Strategy & War
An isometric real-time strategy game inspired by Age of Empires. Gather resources, build a base, and destroy the AI's Town Center.
PropertyValue
Thumbnailaspect-ratio 16/10, bg #111, emoji centered at 3rem
Filtergrayscale(100%) opacity 0.8 → grayscale(0%) opacity 1 on hover (0.5s)
Badgeposition: absolute top-left, bg #fff, color #000, 0.6rem/900/uppercase
Title1.1rem / 700 / uppercase / ls -0.01em; translateX(4px) on hover (0.3s)
Meta0.65rem / uppercase / ls 0.1em / color #888
Description0.8rem / color #666 / lh 1.55 / 2-line clamp
Grid3 columns desktop, 2 columns ≤768px, 1 column ≤480px

Ticker Strip

Full-width auto-scrolling strip with seamless loop. Animates on all screen sizes.

Ticker Strip Preview
Auto-scrolling left-to-right, pause on hover

PropertyValue
PositionTop of page, above main content
HeightAuto (content-based)
Background#050505
Border1px solid #1a1a1a (bottom)
Animation40s linear infinite (translateX 0 → -50%)
On Hoveranimation-play-state: paused
Edge Mask::before / ::after gradient fades (left/right)
Seamless LoopJS duplicates all items (second copy hidden visually)

Mini Card Strip

Horizontal swipeable carousel showing project emoji + name. Mobile-only component.

Card Strip Preview
Swipeable on mobile (overflow-x: auto), -webkit-overflow-scrolling: touch

PropertyValue
DisplayMobile only (@media max-width: 480px)
Overflowoverflow-x: auto; scrollbar hidden
Scroll Behavior-webkit-overflow-scrolling: touch (momentum scroll)
Card Sizingflex-shrink: 0; min-width: 76px
Card Gap0.5rem
Padding1rem 1.25rem (vertical | horizontal)
Card ContentEmoji icon + project name (centered)

Spacing Scale

0.25rem
Footer link separators, small gaps
0.4rem
Breadcrumb gap
0.5rem
Footer mobile gap, brand item gap
0.6rem
Button vertical padding
0.75rem
Breadcrumb padding, input vertical padding
1rem
Standard gap, modal links, input horizontal
1.25rem
Mobile project item gap, logo card padding
1.5rem
Footer padding, section sub-spacing
1.75rem
Desktop project item gap
2rem
Horizontal page padding, auth gate padding
2.5rem
Auth gate padding, hero top spacing
3rem
Main content top padding, section spacing
4rem
Main content bottom padding

Border Radius

2px
Wave bars
4–6px
TOC / Inset box
8px
Modal / Inputs / Auth btn
12px
Logo Cards
16px
Auth Gate Modal
999px
Pill Buttons
50%
Circles / Animations

Transitions & Motion

DurationPropertiesUsed on
0.15s color Breadcrumb links, project arrows, text links
0.2s background, border-color, transform, box-shadow Buttons (hover), inputs (focus), logo cards (hover)
0.3s color, transform Briefing link on root page; recent card title slide
0.5s opacity, transform, filter, width Category tile icon fade/scale; recent card grayscale; tile bottom-border expand

Hover Transforms

ElementTransform
Project card arrow →translateX(3px)
Logo cardtranslateY(-3px)
Recent card titletranslateX(4px)
Category tile iconscale(1.1)

Responsive Breakpoints

BreakpointApplies toKey Changes
max-width: 768px Gallery hub, Games, Explorations pages Recent grid: 3→2 columns; project grid view: 3→2 columns
max-width: 768px Brands / logo grid Grid: 3 columns (down from 4), gap 0.75rem
max-width: 640px Full-screen games (test4) Mobile breadcrumb bar replaces sidebar
max-width: 480px All pages (primary mobile breakpoint) h1 → 1.9rem; padding → 1.25rem horiz; footer stacks vertically; logo grid → 2 columns

Baseline mobile target: 375px (iPhone SE). All layouts use width: 100% with max-width caps — never fixed widths. Content pages: max-width: 760px. Grid / dashboard pages: max-width: 960px. Gallery / hub pages (projects, games, explorations): max-width: 1100px.

Z-Index Layers

z-indexLayer
99999Auth gate (#ct-auth-gate) — always on top
100Quick Links modal overlay
1–10Sticky headers, game overlays (project-specific)
0Default page content