디자인 시스템을 다시 짠다는 것
색 한 톤을 바꾸려다 결국 토큰 레이어 전체를 다시 정리했습니다.
이번 호. 토큰 78개, 컴포넌트 4개, 결정 한 묶음.
Primary #2563EB (Tailwind Blue 600). 흰 배경 위 대비 5.2:1로 WCAG AA 통과.
다크는 반대로 #60A5FA. Surface와 border용 옅은 톤은 별도 정의 없이
color-mix로 텍스트 색에서 파생.
color: var(--text-primary);
background: var(--surface-raised);
border: 1px solid var(--border-default); 의미 토큰을 쓰면 다크 모드에서 자동으로 반전됩니다.
color: var(--text-primary);
border: 1px solid var(--border-subtle); hex 리터럴은 라이트 한정 — 다크 배경 위에서 텍스트가 사라집니다.
color: #121212;
border: 1px solid #e5e5e5; text
surface
border
accent
Pretendard 한 패밀리. 의미 기반 9단계 — display, heading, body, caption, code. 본문은 500 weight 기본 (한글 가독성).
--font-sans Pretendard, system-ui, sans-serif 디자인 시스템 — 본문
--font-mono Fira Code, JetBrains Mono, SF Mono, monospace const tokens = useDesign();
| Token | Size / Weight | Sample |
|---|---|---|
| display-1 | 44 / 800 | 디자인 노트 |
| display-2 | 32 / 700 | 디자인 노트 |
| heading-1 | 26 / 700 | 디자인 노트 |
| heading-2 | 20 / 700 | 디자인 노트 |
| heading-3 | 18 / 600 | 디자인 노트 |
| body-lg | 17 / 500 | 한 줄에 65자 내외가 가장 편한 호흡. |
| body | 15 / 500 | 본문 기본 크기. |
| body-sm | 14 / 500 | 보조 본문, 카드 설명. |
| caption | 13 / 500 | 메타데이터, 날짜 |
| label | 13 / 600 | form label |
| code | 14 / 400 · mono | const tokens; |
@include heading-1;
@include body;
font-family: var(--font-mono); 4가지 기초 토큰 — Space (4px base, 11단계), Radius (5), Shadow (5, 다크 alpha 가산), Motion (4 duration + 4 easing).
--duration-fast 100ms --duration-base 150ms --duration-slow 250ms --duration-slower 400ms | Token | Value | Usage |
|---|---|---|
--easing-standard | cubic-bezier(0.4, 0, 0.2, 1) | 일반 인터랙션 |
--easing-emphasized | cubic-bezier(0.16, 1, 0.3, 1) | 모달/시트 진입 (spring) |
--easing-decelerate | cubic-bezier(0, 0, 0.2, 1) | 밖에서 안으로 |
--easing-accelerate | cubic-bezier(0.4, 0, 1, 1) | 안에서 밖으로 |
| Name | Width | Range |
|---|---|---|
$mobile | 480px | 모바일 이상 |
$tablet | 768px | 태블릿 이상 |
$desktop | 1024px | 데스크탑 이상 |
$widescreen | 1440px | 와이드 |
| Token | Value | Layer |
|---|---|---|
--z-dropdown | 10 | 드롭다운 |
--z-sticky | 20 | sticky 헤더 |
--z-overlay | 40 | 배경 오버레이 |
--z-modal | 50 | 모달 |
--z-popover | 60 | 팝오버 |
--z-toast | 70 | 토스트 |
--z-tooltip | 80 | 툴팁 |
padding: var(--space-4) var(--space-5);
border-radius: var(--radius-md);
box-shadow: var(--shadow-md);
transition: background var(--duration-base) var(--easing-standard); 토큰만 정의하는 시스템은 시스템이 아닙니다. 실제 페이지에서 같이 일하는 조각들.
<button class="btn btn-primary">Primary</button> 색 한 톤을 바꾸려다 결국 토큰 레이어 전체를 다시 정리했습니다.
<article class="card">
<h3>...</h3>
<p>...</p>
<div class="card-foot">
<Chip>tag</Chip>
<time>2026.05.22</time>
</div>
</article> <Chip variant="active">active</Chip>
<Chip>default</Chip>
<Chip as="button" type="button">click</Chip>
<Chip variant="muted">+12</Chip> 설명에 곁가지로 다는 보충 메모입니다.
아직 검증되지 않은 가정이거나 잠시 멈춰서 봐야 할 부분.
실패한 결정, 되돌린 변경, 또는 알려진 문제.
<aside class="note note-info">
<span class="note-mark">info</span>
<p>...</p>
</aside> 대비, 포커스, 모션 — 접근성은 따로 떨어진 항목이 아니라 모든 토큰에 박혀 있는 약속입니다.
| Token | Ratio | WCAG |
|---|---|---|
--text-primary · #121212 | 18.9:1 | AAA |
--text-secondary · #3f3f3f | 10.4:1 | AAA |
--text-muted · #575757 | 7.0:1 | AAA |
--text-disabled · #666666 | 5.7:1 | AA |
--accent-default · #2563EB | 5.2:1 | AA |
--shadow-focus-ring · 3px primary 30% alpha prefers-reduced-motion이 설정된 사용자에겐 transition과 transform 애니메이션을
자동으로 축소합니다. 모든 motion 토큰은 reduced 환경에서 0ms로 폴백할 수 있도록 디자인.
실제 글 안에서 자주 등장하는 단위 — 인용, 목록, 인라인 코드, 코드 블록, 캡션 있는 이미지. 포스트 본문에서 일관된 모양으로 동작합니다.
가장 흐릿한 잉크가 가장 또렷한 기억보다 낫다.
본문 내 링크는 jiun.dev 처럼
--text-link 토큰 색으로 강조되고, 호버 시 강조됩니다.
본문 안에서 var(--primary-c1) 같은 변수를 언급하거나,
파일 경로 src/styles/base/_tokens.scss를 지칭할 때 사용.
const tokens = {
text: { primary: '#121212', secondary: '#3f3f3f' },
surface: { base: '#ffffff', raised: '#fafafa' },
accent: { default: '#2563EB', hover: '#1D4ED8' },
};