🧩 Design System2. Color System (OKLCH·다크모드)📖 개요

02 — Color System

이 챕터가 답하는 질문: 디자인 시스템의 색은 어떻게 시스템이 되는가? 단순히 --primary-500: #3370b8 하나 던지는 것과 무엇이 다른가? 한 줄 답 (Pyramid Top): 디자인 시스템의 색은 색공간 → scale → contrast pair → theme → 합성식 → 토큰 매핑 의 6-레이어 파이프라인이다. OKLCH로 좌표를 잡고, Radix 12-step로 의미를 박고, APCA로 검증하고, semantic 토큰으로 다크모드를 전환하고, color-mix()로 상호작용을 파생하고, 같은 토큰 1세트를 Panda와 Tailwind에 동시에 주입한다.


Why — 왜 별도 챕터인가

frontend-css/05-color-visualCSS의 색 기능을 설명한다 — oklch() 함수의 문법, color-mix()의 인자, gradient의 보간 등. 이 챕터는 그 위에 시스템을 얹는다.

질문frontend-css/05design-system/02
OKLCH 함수 문법(참조만)
왜 디자인 시스템이 OKLCH로 가는가
step 1~12에 어떤 의미를 매길까
WCAG vs APCA 어느 쪽으로 토큰을 검증할까
다크모드를 토큰 이름은 유지하고 어떻게 바꿀까
같은 색 1세트를 Panda × Tailwind에 어떻게 동시에 줄까

CSS는 색을 표현하는 문법이고, 디자인 시스템은 색을 약속으로 만드는 규약이다.


How — 6-레이어 파이프라인

각 레이어는 이전 레이어의 결정 위에서만 의미가 있다. 색공간을 안 정하고 scale을 짜면 다크모드에서 명도가 무너지고, scale 의미가 모호하면 컴포넌트마다 step을 다르게 쓴다.


What — 6개 파일 인덱스

#파일다루는 것핵심 키워드
0101-color-space-for-design-systemssRGB·P3·LCH·OKLCH 비교, 왜 디자인 시스템이 OKLCH를 택하는가, sRGB fallback 페어OKLCH, gamut mapping, perceptually uniform
0202-color-scale-12-stepRadix Colors의 12-step 의미 매핑, step별 역할(app bg / component / solid / text)Radix Colors, 12-step, semantic role
0303-contrast-and-accessibilityWCAG 2.1 contrast ratio vs APCA Lc, 토큰에 contrast pair 박아넣기WCAG, APCA, Lc, contrast pair
0404-dark-mode-token-strategydata-theme="dark" + CSS variables, color-scheme, prefers-color-schemedark mode, color-scheme, semantic token
0505-color-mix-and-dynamic-themescolor-mix(in oklch, ...)로 hover/active state, opacity tint 동적 생성color-mix, hover state, dynamic tint
0606-color-token-mapping-panda-tailwind같은 OKLCH 1세트를 panda.config.tstailwind.config.ts에 동시 주입preset, codegen, token bridge

What-if — 이 챕터를 건너뛰면

  • Step의 의미가 컴포넌트마다 다르다: A 컴포넌트는 gray-50을 hover bg로, B 컴포넌트는 gray-100을 hover로 → 같은 hover인데 시각 위계가 흔들린다.
  • 다크모드를 값 교체로 처리: --primary-500을 다크에선 --primary-300으로 swap → 라이트/다크에서 step의 의미가 어긋난다. 옳은 패턴은 step은 그대로, 의미적 토큰의 매핑만 교체.
  • WCAG만 믿었더니 노란 텍스트가 통과: WCAG 2.1은 색공간 인지 비대칭을 무시한다. APCA로 재검증하면 떨어진다.
  • Tailwind는 hex, Panda는 OKLCH → gamut이 안 맞아 hover 색이 두 시스템에서 다른 결과.

Insight — 왜 2024~2026이 “Color System의 르네상스”인가

2023년 12월 Tailwind v4 alpha가 기본 팔레트를 전부 OKLCH로 재계산해서 발표했다. 같은 분기에 Radix Colors 3.0이 OKLCH 기반 12-step을 P3 페어와 함께 출시했다. 2024년 Open Props 1.7이 OKLCH ramp를 1급 시민으로 올렸다.

세 사건이 같은 분기에 일어난 건 우연이 아니다 — CSS Color 4가 모든 메이저 브라우저에서 안정화된 시점이 2023년 9월(Firefox 113이 마지막)이었고, 그 직후 각 디자인 시스템이 OKLCH로 갈아탈 안전한 시점이 됐다.

이전엔 색의 디자인 시스템화가 경험적이었다 — “이 색은 hover로 너무 진하니까 조금 연하게”. 이제는 수학적이다 — “step 4는 step 3에서 L을 -3% 이동한 값”. 같은 회사 다른 팀 다른 제품의 hover가 같은 수식으로 나온다는 게 OKLCH 시스템의 핵심 가치다.


요약

  • 색은 6-레이어 파이프라인 — 공간 → scale → contrast → theme → composition → token mapping.
  • OKLCH가 사실상 표준 (2024년 Tailwind v4 / Radix 3 / Open Props).
  • Radix 12-step이 step별 의미의 사실상 표준 (1-2 bg, 3-5 component, 9 solid, 11-12 text).
  • APCA가 WCAG 2.1을 보강. 둘 다 보는 게 안전.
  • Panda × Tailwind 호환은 토큰을 바깥에 두는 게 답.

다음: 01-color-space-for-design-systems — 왜 디자인 시스템이 sRGB·HSL을 떠나는가.