디자인 시스템을 위한 색상 시스템 구축
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
임시방편적인 색상 선택이 쌓이면 혼돈이 됩니다. 한 컴포넌트에서 #3B82F6으로, 다른 곳에서 #2563EB로, 또 다른 곳에서 rgba(59, 130, 246, 0.8)로 지정된 브랜드 파란색 — 모두 명목상 "같은" 파란색 — 은 브랜드 일관성을 약화시키고, 다크 모드 구현을 신뢰할 수 없게 만들고, 모든 색상 변경을 코드베이스 고고학 프로젝트로 만드는 시각적 불일치를 만들어냅니다.
색상 시스템은 두 개의 레이어로 구성된 인터페이스의 모든 색상에 대한 단일 진실 소스를 확립하여 이를 해결합니다: 사용 가능한 모든 색상 값의 기본 팔레트와 그 기본 색상을 의도된 역할에 매핑하는 시맨틱 토큰 레이어. 이 분리를 통해 컴포넌트 코드를 건드리지 않고 시맨틱 토큰 할당을 변경하는 것만으로 다크 모드, 고대비 모드, 브랜드 리스킨을 구축할 수 있습니다.
이 가이드는 기본 팔레트 선택, 쉐이드 스케일 생성, 시맨틱 토큰 정의, CSS와 Tailwind에서의 구현, 문서화 및 테스트 설정까지 처음부터 완전한 프로덕션 준비 색상 시스템을 구축하는 방법을 안내합니다.
체계적인 색상이 중요한 이유
체계적인 색상에 대한 주장은 미학적인 것이 아닌 운영적인 것입니다. 시스템 없이 무엇이 잘못되는지:
불일치가 시간이 지남에 따라 누적됩니다: 프로젝트 초기에 디자이너와 개발자는 "좋아 보이는" 임시방편적인 색상 결정을 합니다. 2년 후 코드베이스는 모두 같은 파란색이어야 하는 40개의 구별되는 파란색 값을 축적합니다. 어떤 것이 올바른지 아무도 모릅니다.
다크 모드는 시맨틱 매핑이 필요합니다: 색상이 시각적 값으로 하드코딩된 경우 다크 모드가 작동할 수 없습니다. color: #1E293B는 밝은 배경의 텍스트로 좋아 보이는 어두운 색상입니다. 다크 모드에서는 다른 값이 필요합니다. 80개의 컴포넌트에 #1E293B를 하드코딩했다면 업데이트할 80개의 위치가 있거나 새로운 기술 부채 레이어를 만드는 복잡한 CSS 재정의 시스템이 있습니다. 시맨틱 토큰이 이것을 제거합니다.
테마 변경이 비쌉니다: 기본 색상을 리브랜딩하거나 변경하는 것은 단일 변경이어야 합니다. 시맨틱 시스템으로 토큰 파일에서 --color-primary-600을 변경하면 그것을 참조하는 모든 버튼, 링크, 포커스 링, 테두리가 자동으로 업데이트됩니다.
접근성 감사가 조용히 실패합니다: 시스템 없이는 모든 텍스트가 WCAG 대비 요구 사항을 충족하는지 확인하려면 모든 텍스트/배경 조합을 수동으로 감사해야 합니다. 시맨틱 토큰으로 규칙을 정의하고("surface-primary의 text-primary는 AA를 통과해야 함") 프로그래매틱하게 테스트할 수 있습니다.
명명 규칙: 기본 대 시맨틱
잘 구성된 색상 시스템은 다른 목적을 위한 두 개의 명명 계층을 가집니다.
기본 색상 토큰
기본 토큰은 스케일에서의 위치로 명명된 원시 색상 값입니다. 사용에 대한 가정이 없습니다. 단순히 사용 가능한 색상의 팔레트입니다:
blue-50 → #EFF6FF
blue-100 → #DBEAFE
blue-200 → #BFDBFE
blue-300 → #93C5FD
blue-400 → #60A5FA
blue-500 → #3B82F6
blue-600 → #2563EB
blue-700 → #1D4ED8
blue-800 → #1E40AF
blue-900 → #1E3A8A
blue-950 → #172554
기본 토큰 이름은 "이 색상은 무엇인가?"에 답합니다. "이 색상은 무엇을 위한 것인가?"에는 답하지 않습니다.
시맨틱 색상 토큰
시맨틱 토큰은 기본 토큰을 참조하고 목적으로 색상을 명명합니다:
color-action-primary → blue-600
color-action-primary-hover → blue-700
color-action-primary-text → white-0
color-surface-default → neutral-50 (라이트 모드) / neutral-900 (다크 모드)
color-surface-elevated → white-0 (라이트 모드) / neutral-800 (다크 모드)
color-text-primary → neutral-900 (라이트 모드) / neutral-50 (다크 모드)
color-text-secondary → neutral-600 (라이트 모드) / neutral-400 (다크 모드)
color-text-disabled → neutral-400 (라이트 모드) / neutral-600 (다크 모드)
color-border-default → neutral-200 (라이트 모드) / neutral-700 (다크 모드)
color-border-focused → blue-500
시맨틱 토큰 이름은 "이 색상은 무엇을 위한 것인가?"에 답합니다. 값을 지정하지 않습니다. 기본 색상을 참조합니다.
이 분리가 핵심 구조적 결정입니다. 컴포넌트는 기본 색상이 아닌 시맨틱 토큰을 참조합니다. 다크 모드를 정의할 때 시맨틱 토큰을 다른 기본 색상에 재매핑합니다. 컴포넌트 코드는 변경되지 않습니다.
실제 명명 체계
다른 디자인 시스템은 시맨틱 레이어에 다른 명명 규칙을 사용합니다:
| 시스템 | 시맨틱 이름 예시 | 규칙 |
|---|---|---|
| Material Design | sys.color.primary |
점으로 구분된 역할 계층 |
| Apple HIG | label, secondaryLabel |
단순 역할 이름 |
| Radix UI | --accent-9, --gray-11 |
스케일 기반 시맨틱 이름 |
| Primer (GitHub) | fgColor.default, bgColor.default |
역할 + 변형 |
규칙보다 일관성이 더 중요합니다. 하나를 선택하고 전체에 적용하세요.
쉐이드 스케일 생성 (50–950)
쉐이드 스케일은 단일 색조 군 내에서 거의 흰색에서 거의 검정까지의 순서 있는 색상 값 시리즈입니다. Tailwind CSS가 50–950 스케일을 대중화했고, Material Design은 100–900을 사용합니다. 특정 숫자보다 사용 사례의 범위를 커버하기에 충분한 단계를 갖는 것이 더 중요합니다: 배경을 위한 매우 밝은 색조, 인터랙티브 요소를 위한 중간 범위 값, 텍스트를 위한 깊은 쉐이드.
좋은 쉐이드 스케일의 조건
사용 가능한 쉐이드 스케일은 두 가지 속성을 가집니다:
- 충분한 지각적 단계: 인접한 쉐이드는 시각적으로 뚜렷해야 합니다. 차이가 인식 불가능할 정도로 가깝지 않고, 커버리지에 간격이 나타날 정도로 멀지 않아야 합니다.
- 일관된 명도 진행: 명도 값은 950(가장 어두운)에서 50(가장 밝은)까지 예측 가능하게 증가해야 하며, 놀라운 점프나 역전이 없어야 합니다.
수동으로 선택된 쉐이드 스케일의 실패 모드는 불규칙한 명도 간격입니다. 쉐이드 300, 400, 500이 모두 지각적으로 유사하고 500에서 700으로 극적으로 점프하는 스케일은 유용하지 않습니다. 범위 중간에 있는 것이 필요할 때 항상 500에 손이 갈 것입니다.
OKLCH에서 쉐이드 생성
OKLCH(OK 명도-채도-색조)는 쉐이드 생성을 위한 최적의 색 공간입니다. 명도 채널이 지각적으로 균일하기 때문입니다. 동일한 수치 단계가 동일한 지각적 단계를 만들어냅니다. L=0.15(매우 어두운)에서 L=0.98(매우 밝은)까지 동일한 간격으로 명도 값을 배치하면 결과 쉐이드가 시각적으로 동일하게 간격을 가집니다.
OKLCH에서 11단계 쉐이드 스케일 생성:
- 기본 색조와 채도를 선택합니다: 예: H=250(파란색), C=0.20.
- 명도 값을 균등하게 배치합니다: L = 0.15, 0.22, 0.30, 0.38, 0.47, 0.55, 0.63, 0.72, 0.82, 0.92, 0.97.
- 선택적으로 채도를 약간 변화시킵니다: 매우 밝고 어두운 극단에서 채도를 줄입니다.
- OKLCH 값을 구현을 위해 헥스로 변환합니다.
파란색 색조에 대한 실용적인 OKLCH-to-헥스 스케일:
Shade | OKLCH | Hex
------+--------------------------+--------
50 | oklch(0.97 0.04 250) | #EFF6FF
100 | oklch(0.92 0.07 250) | #DBEAFE
200 | oklch(0.84 0.11 250) | #BFDBFE
300 | oklch(0.74 0.16 250) | #93C5FD
400 | oklch(0.65 0.19 250) | #60A5FA
500 | oklch(0.55 0.22 250) | #3B82F6
600 | oklch(0.47 0.22 250) | #2563EB
700 | oklch(0.40 0.20 250) | #1D4ED8
800 | oklch(0.32 0.18 250) | #1E40AF
900 | oklch(0.24 0.14 250) | #1E3A8A
950 | oklch(0.17 0.10 250) | #172554
ColorFYI의 쉐이드 생성기를 사용하여 기본 색상에서 Tailwind 스타일 쉐이드 스케일을 생성하고, 색상 변환기를 사용하여 OKLCH 공간에서 각 생성된 쉐이드를 검사하여 명도 진행을 확인하세요.
몇 개의 쉐이드 단계가 필요한가?
대부분의 디자인 시스템에서 9–11단계가 적절한 범위입니다:
- 50과 950: 서피스 배경과 가장 어두운 텍스트/테두리 사용을 위한 가장자리 값.
- 100–200: 밝은 색조 배경(경보 배경, 흰색 서피스의 호버 상태).
- 300–400: 아이콘 색상, 플레이스홀더 텍스트, 비활성화 상태.
- 500: 종종 "순수한" 브랜드 색상 — 브랜드 색상 표준이 지정하는 것.
- 600–700: 인터랙티브 요소 채우기(흰색에 대한 대비가 필요한 버튼, 링크).
- 800–900: 텍스트 및 색상 배경의 텍스트 사용.
팔레트의 모든 색조 군에 대해 쉐이드를 생성하세요: 기본 브랜드 색상, 중성 회색 시리즈, 모든 악센트 색상(빨강/오류, 초록/성공, 노랑/경고 등).
시맨틱 색상 토큰
기본 색상이 확립되면 기본 색상을 역할에 매핑하는 시맨틱 토큰을 정의합니다. 이 매핑의 세분화도가 시스템의 유연성을 결정합니다.
서피스 색상
서피스 토큰은 UI의 배경 레이어를 정의합니다:
:root {
--color-surface-base: var(--neutral-50); /* 페이지 배경 */
--color-surface-elevated: var(--white); /* 카드, 시트 배경 */
--color-surface-overlay: var(--white); /* 모달, 팝오버 배경 */
--color-surface-sunken: var(--neutral-100); /* 인셋 필드, 코드 블록 */
}
[data-theme="dark"] {
--color-surface-base: var(--neutral-950);
--color-surface-elevated: var(--neutral-900);
--color-surface-overlay: var(--neutral-800);
--color-surface-sunken: var(--neutral-950);
}
텍스트 색상
텍스트 토큰은 계층의 모든 텍스트 역할을 커버합니다:
:root {
--color-text-primary: var(--neutral-900); /* 본문 텍스트, 제목 */
--color-text-secondary: var(--neutral-600); /* 캡션, 라벨 */
--color-text-tertiary: var(--neutral-400); /* 플레이스홀더, 힌트 */
--color-text-disabled: var(--neutral-300); /* 비활성화 상태 */
--color-text-inverse: var(--white); /* 어두운/색상 배경의 텍스트 */
--color-text-link: var(--blue-600);
--color-text-link-hover: var(--blue-700);
}
[data-theme="dark"] {
--color-text-primary: var(--neutral-50);
--color-text-secondary: var(--neutral-400);
--color-text-tertiary: var(--neutral-600);
--color-text-disabled: var(--neutral-700);
--color-text-link: var(--blue-400);
--color-text-link-hover: var(--blue-300);
}
인터랙티브 / 액션 색상
액션 토큰은 인터랙티브 요소의 모든 상태를 커버합니다:
:root {
/* 기본 액션 */
--color-action-primary-bg: var(--blue-600);
--color-action-primary-bg-hover: var(--blue-700);
--color-action-primary-bg-active: var(--blue-800);
--color-action-primary-text: var(--white);
/* 보조 / 고스트 액션 */
--color-action-secondary-border: var(--blue-600);
--color-action-secondary-text: var(--blue-600);
--color-action-secondary-bg-hover: var(--blue-50);
/* 파괴적 액션 */
--color-action-danger-bg: var(--red-600);
--color-action-danger-bg-hover: var(--red-700);
--color-action-danger-text: var(--white);
}
피드백 / 상태 색상
상태 토큰은 기능적 색상을 시맨틱 의미에 매핑합니다:
:root {
/* 성공 */
--color-status-success-bg: var(--green-50);
--color-status-success-border: var(--green-200);
--color-status-success-text: var(--green-700);
--color-status-success-icon: var(--green-500);
/* 경고 */
--color-status-warning-bg: var(--yellow-50);
--color-status-warning-border: var(--yellow-200);
--color-status-warning-text: var(--yellow-800);
--color-status-warning-icon: var(--yellow-500);
/* 오류 */
--color-status-error-bg: var(--red-50);
--color-status-error-border: var(--red-200);
--color-status-error-text: var(--red-700);
--color-status-error-icon: var(--red-500);
/* 정보 */
--color-status-info-bg: var(--blue-50);
--color-status-info-border: var(--blue-200);
--color-status-info-text: var(--blue-700);
--color-status-info-icon: var(--blue-500);
}
테두리 색상
:root {
--color-border-default: var(--neutral-200);
--color-border-strong: var(--neutral-400);
--color-border-focused: var(--blue-500);
--color-border-error: var(--red-500);
--color-border-disabled: var(--neutral-200);
}
[data-theme="dark"] {
--color-border-default: var(--neutral-700);
--color-border-strong: var(--neutral-500);
--color-border-focused: var(--blue-400);
--color-border-error: var(--red-400);
--color-border-disabled: var(--neutral-700);
}
CSS에서의 구현
CSS 구현은 :root 레벨(또는 테마를 위한 [data-theme] 선택자)에서 정의된 커스텀 속성을 사용합니다. 컴포넌트는 기본 색상이 아닌 시맨틱 토큰만 참조합니다.
파일 구조
design-system/
├── tokens/
│ ├── primitives.css # 모든 기본 색상 값
│ ├── semantic.css # 시맨틱 토큰 → 기본 색상 매핑
│ └── dark.css # 다크 모드 시맨틱 재정의
└── components/
├── button.css
├── card.css
└── ...
primitives.css
:root {
/* 중성 스케일 */
--neutral-50: #F8FAFC;
--neutral-100: #F1F5F9;
--neutral-200: #E2E8F0;
--neutral-300: #CBD5E1;
--neutral-400: #94A3B8;
--neutral-500: #64748B;
--neutral-600: #475569;
--neutral-700: #334155;
--neutral-800: #1E293B;
--neutral-900: #0F172A;
--neutral-950: #020617;
/* 파란색 스케일 */
--blue-50: #EFF6FF;
--blue-100: #DBEAFE;
--blue-200: #BFDBFE;
--blue-300: #93C5FD;
--blue-400: #60A5FA;
--blue-500: #3B82F6;
--blue-600: #2563EB;
--blue-700: #1D4ED8;
--blue-800: #1E40AF;
--blue-900: #1E3A8A;
--blue-950: #172554;
/* 흰색과 검정 */
--white: #FFFFFF;
--black: #000000;
}
컴포넌트 사용
컴포넌트는 시맨틱 토큰만 참조합니다:
.button-primary {
background-color: var(--color-action-primary-bg);
color: var(--color-action-primary-text);
border: none;
}
.button-primary:hover {
background-color: var(--color-action-primary-bg-hover);
}
.button-primary:active {
background-color: var(--color-action-primary-bg-active);
}
.button-primary:disabled {
background-color: var(--neutral-200); /* 예외: 비활성화 상태는 종종 기본 색상 사용 */
color: var(--color-text-disabled);
}
테마가 라이트에서 다크로 변경되면 --color-action-primary-bg가 자동으로 다른 값으로 해결됩니다. 버튼별 다크 모드 재정의가 필요 없습니다.
Tailwind CSS에서의 구현
Tailwind v3와 v4는 설정 파일과 CSS 변수 접근 방식을 통해 디자인 토큰 통합을 지원합니다.
Tailwind v3 설정
tailwind.config.js에서 색상 스케일을 정의하고 CSS 커스텀 속성에 매핑합니다:
// tailwind.config.js
const colors = require("tailwindcss/colors");
module.exports = {
theme: {
colors: {
transparent: "transparent",
current: "currentColor",
white: "#ffffff",
black: "#000000",
// 기본 스케일
neutral: {
50: "#F8FAFC",
100: "#F1F5F9",
200: "#E2E8F0",
300: "#CBD5E1",
400: "#94A3B8",
500: "#64748B",
600: "#475569",
700: "#334155",
800: "#1E293B",
900: "#0F172A",
950: "#020617",
},
blue: {
50: "#EFF6FF",
100: "#DBEAFE",
200: "#BFDBFE",
300: "#93C5FD",
400: "#60A5FA",
500: "#3B82F6",
600: "#2563EB",
700: "#1D4ED8",
800: "#1E40AF",
900: "#1E3A8A",
950: "#172554",
},
// CSS 변수를 통한 시맨틱 토큰
"action-primary": "var(--color-action-primary-bg)",
"action-primary-hover": "var(--color-action-primary-bg-hover)",
"surface": "var(--color-surface-base)",
"surface-elevated": "var(--color-surface-elevated)",
"text-primary": "var(--color-text-primary)",
"text-secondary": "var(--color-text-secondary)",
"border-default": "var(--color-border-default)",
},
},
};
이 설정으로 bg-action-primary를 작성하면 올바른 시맨틱 토큰 값으로 해결되고, 이는 다시 현재 테마에 대한 올바른 기본 색상으로 해결됩니다.
Tailwind v4 CSS 우선 설정
Tailwind v4는 @theme을 사용하는 CSS 우선 접근 방식으로 JavaScript 설정을 대체합니다:
@import "tailwindcss";
@theme {
/* 기본 색상 */
--color-blue-500: #3B82F6;
--color-blue-600: #2563EB;
--color-blue-700: #1D4ED8;
--color-neutral-50: #F8FAFC;
--color-neutral-900: #0F172A;
/* 시맨틱 토큰 */
--color-surface: var(--color-surface-base);
--color-text: var(--color-text-primary);
--color-primary: var(--color-action-primary-bg);
}
/* 시맨틱 정의 */
:root {
--color-surface-base: var(--color-neutral-50);
--color-text-primary: var(--color-neutral-900);
--color-action-primary-bg: var(--color-blue-600);
}
[data-theme="dark"] {
--color-surface-base: oklch(0.145 0 0);
--color-text-primary: var(--color-neutral-50);
--color-action-primary-bg: var(--color-blue-500);
}
테스트 및 문서화
색상 시스템은 팀의 모든 사람이 이해하고 신뢰할 수 있게 구현할 때만 유용합니다. 테스트는 회귀를 잡습니다. 문서화는 시스템을 학습 가능하게 만듭니다.
대비 테스트
의도된 배경 서피스 토큰과 쌍을 이루는 모든 텍스트 토큰은 WCAG 2.1 AA 요구 사항을 충족하는지 프로그래매틱하게 확인해야 합니다(일반 텍스트의 경우 4.5:1, 큰 텍스트의 경우 3:1). 다음을 수행하는 테스트를 작성하세요:
- 현재 CSS 커스텀 속성 값을 해결합니다(라이트 및 다크 테마 모두).
- 각 텍스트/서피스 쌍 사이의 WCAG 대비 비율을 계산합니다.
- 비율이 필요한 임계값을 충족하는지 단언합니다.
import { getContrastRatio } from "some-color-utility";
const tokens = {
light: {
textPrimary: "#0F172A",
surfaceBase: "#F8FAFC",
},
dark: {
textPrimary: "#F8FAFC",
surfaceBase: "#020617",
}
};
describe("색상 시스템 대비", () => {
test("라이트 모드에서 surface-base의 text-primary가 AA를 통과합니다", () => {
const ratio = getContrastRatio(tokens.light.textPrimary, tokens.light.surfaceBase);
expect(ratio).toBeGreaterThanOrEqual(4.5);
});
test("다크 모드에서 surface-base의 text-primary가 AA를 통과합니다", () => {
const ratio = getContrastRatio(tokens.dark.textPrimary, tokens.dark.surfaceBase);
expect(ratio).toBeGreaterThanOrEqual(4.5);
});
});
토큰 정의 중 개별 토큰 쌍의 수동 확인에는 ColorFYI의 대비 확인기를 사용하세요.
색상 토큰 문서화
각 시맨틱 토큰을 다음과 함께 문서화하세요: - 이름: 정확한 CSS 변수 이름. - 값 (라이트): 라이트 모드에서 참조하는 기본 색상. - 값 (다크): 다크 모드에서의 기본 색상. - 사용: 이 토큰을 사용해야 하는 곳. - 안티 패턴: 사용하지 말아야 하는 곳.
| 토큰 | 라이트 | 다크 | 사용 |
|------------------------------|----------------|----------------|--------------------------------|
| --color-text-primary | neutral-900 | neutral-50 | 본문 텍스트, 제목 |
| --color-text-secondary | neutral-600 | neutral-400 | 캡션, 메타데이터, 라벨 |
| --color-action-primary-bg | blue-600 | blue-500 | 기본 버튼 배경 |
| --color-surface-elevated | white | neutral-900 | 카드, 시트, 패널 배경 |
시각적 회귀 테스트
Percy, Chromatic 또는 Playwright의 스크린샷 비교와 같은 도구를 사용하여 토큰 문서화와 시각적 회귀 테스트를 연결하세요. 시각적 회귀 테스트는 각 토큰 변경 시 컴포넌트 라이브러리를 렌더링하고, 스크린샷을 캡처하여 기준선과 비교합니다. 색상 변경이 있으면 검토가 트리거되어 우발적 회귀를 포착합니다.
Storybook 색상 팔레트 페이지
Storybook에서 모든 토큰을 스워치로 렌더링하는 전용 색상 팔레트 스토리를 만드세요:
// ColorPalette.stories.jsx
const tokens = [
{ name: "--color-surface-base", label: "Surface / Base" },
{ name: "--color-surface-elevated", label: "Surface / Elevated" },
{ name: "--color-text-primary", label: "Text / Primary" },
// ...
];
export function ColorPaletteDoc() {
return (
<div>
{tokens.map(({ name, label }) => (
<div key={name} style={{ display: "flex", alignItems: "center", gap: 16 }}>
<div style={{
width: 48,
height: 48,
backgroundColor: `var(${name})`,
borderRadius: 4,
border: "1px solid rgba(0,0,0,0.1)"
}} />
<div>
<div>{label}</div>
<code>{name}</code>
</div>
</div>
))}
</div>
);
}
이것은 Storybook에서 활성화된 어떤 테마든 실제 라이브 토큰 값을 렌더링합니다. 정적이 아닌 자기 검증 문서화를 만들어냅니다.
핵심 요약
- 색상 시스템은 기본 토큰(스케일에서의 값 위치로 명명:
blue-600)을 시맨틱 토큰(목적으로 명명:color-action-primary-bg)으로 분리합니다. 컴포넌트는 항상 시맨틱 토큰을 참조하고 기본 색상은 절대 참조하지 않습니다. - 이 분리는 CSS 커스텀 속성 레벨에서 시맨틱 토큰을 다른 기본 색상에 재매핑하는 것으로 컴포넌트 코드 변경 없이 다크 모드와 테마를 가능하게 합니다.
- 명도 채널이 지각적으로 균일한 OKLCH 색 공간을 사용하여 쉐이드 스케일(50–950)을 생성합니다. 동일한 수치 단계가 동일하게 간격을 가진 시각적 결과를 만들어냅니다. ColorFYI의 쉐이드 생성기를 사용하여 앵커 색상에서 Tailwind 호환 쉐이드 스케일을 만드세요.
- 시맨틱 토큰 카테고리는 네 가지 영역을 커버합니다: 서피스(배경 레이어), 텍스트(텍스트 역할의 계층), 액션(인터랙티브 요소 상태), 피드백(성공, 경고, 오류, 정보).
- CSS에서 기본 색상을 한 파일에, 시맨틱 매핑을 다른 파일에 정의하세요. 다크 모드를 위해 시맨틱 토큰을 재매핑하는
[data-theme="dark"]선택자 재정의를 사용하세요. - Tailwind v3에서는 CSS 커스텀 속성 참조로 설정의 색상 객체를 확장합니다. Tailwind v4에서는 CSS 우선
@theme블록을 사용하여 기본 색상과 시맨틱 토큰을 모두 정의합니다. - 모든 텍스트/서피스 토큰 쌍을 WCAG 대비 준수에 대해 프로그래매틱하게 테스트합니다. 수동 확인만이 아닙니다. 토큰 정의 중 수동 확인에는 ColorFYI의 대비 확인기를 사용하세요.
- 실제 CSS 커스텀 속성 값을 렌더링하는 라이브 스워치로 Storybook에서 토큰을 문서화하여 문서화가 시스템의 실제 현재 상태를 반영하도록 하세요.