컬러 팔레트 디자이너
좋아 보이면서 대비도 통과하는 색상은 하나의 프로세스를 따릅니다: 분위기에 맞는 색조를 선택한 다음, 수학으로 명도를 고정하는 것입니다. 하모니 휠, 60-30-10 규칙, 색상 심리학 차트는 사용성 증거가 없는 시작용 휴리스틱일 뿐입니다. 대비, 절제(하나의 액션 색조), 주변과 구분되는 강조색이 실제로 유효한 부분입니다. 이 부분을 위해 설계하세요.
모든 숫자는 scripts/palette.mjs(의존성 없는 Node)에서 제공됩니다. 비율이나 OKLCH 값을 수동으로 추정하는 대신 이 스크립트를 실행하세요; 수동으로 계산한 대비는 종종 틀리기 때문에 중요합니다(이 스킬의 기반이 된 연구에서 여러 값이 0.05~0.15 정도 차이 났습니다).
S=<skill-dir>/scripts/palette.mjs
node $S contrast '#767676' '#ffffff' # 4.54:1, 등급, APCA Lc
node $S oklch '#3F6B4E' # 정확한 OKLCH
node $S solve '#C0643F' '#FFFFFF' 4.5 darker # 통과할 때까지 L만 조정
node $S ramp 155 0.12 # 50-950 OKLCH 램프
node $S generate --hue 155 --chroma 0.07 --neutral-hue 95 --accent-offset -110 --format report
node $S generate ... --format css # 또한: css-light-dark | json | dtcg
node $S audit sage-wellness # 큐레이션된 팔레트 ID 또는 roles .json 파일
node $S presets # area-split 및 state-mix 프리셋
node $S ratio 70 25 5 --preset calm # 영역 분할 검증 (가시 영역의 백분율)
node $S states sage-wellness --css # hover/active/disabled/tint 믹스 해결 + 검사
node $S dark midnight-terminal # 다크 모드 규칙 D1-D11 (--light <id|file>, --oled 추가 가능)
node $S cvd '#0072B2' '#D55E00' '#009E73' # 색맹 분리 검사
audit, generate, dark, states, ratio 명령어는 실패하는 쌍이나 FAIL 규칙이 있으면 0이 아닌 값을 반환하므로, 사용자에게 무언가를 보여주기 전에 게이트로 사용하세요. 다크 모드의 경우 generate와 audit이 자동으로 다크 규칙을 실행합니다.
워크플로우: 간략 요구사항에서 검증된 팔레트까지
- 요구사항 분석. 브랜드 색상, 분위기 단어, 업종, 대상 사용자(나이, 시력), 모드(라이트, 다크 또는 둘 다), 준수 수준(기본 AA, 건강/정부/고령 대상은 AAA 본문 텍스트). 사용자가 분위기만 언급했다면 아래 결정 테이블에서 색조를 선택하고 한 줄로 가정을 명시한 후 질문하지 마세요.
- 전략 선택. 기본값은 틴트된 중립 + 하나의 기본색(+ 선택적 강조색 하나). 모노크롬에 의미론적 색상을 더하는 것이 가장 안전합니다. CTA를 돋보이게 하려면(고립 효과) 보색을 사용하세요. 삼색 및 사색 구성은 차트와 일러스트레이션에 적합하며 UI 크롬에는 거의 사용되지 않습니다.
- 앵커 색조와 채도 설정. 브랜드 헥스 값이 있으면
oklch를 실행하고 그 색조를 유지하세요. 채도는 어스/웰니스의 경우 약 0.12 이하, 생동감/테크의 경우 0.20-0.26으로 제한하세요. 브랜드 색상이 없으면 해당 카테고리의 명백한 경쟁사와 구별되는 색조를 선택하세요. - 생성.
generate는 각 모드에 대해 중립, 기본, 강조, 의미론적 역할을 구축하고 대비 목표가 충족되도록 명도를 해결합니다. 수동 팔레트의 경우ramp로 램프를 구축하고 단계를 역할에 매핑하세요(아래 테이블 참조). - 모든 쌍 검증
audit으로. 실패 시 명도만 이동(solve)하고 색조는 절대 변경하지 마세요. 색상이 sRGB를 벗어나면 채도를 줄이세요. 큐레이션된 15개 팔레트의 모든 실패는 중간 명도, 높은 채도의 강조색(OKLCH L 약 0.60-0.77)에서 발생했습니다: 흰색 텍스트에 너무 밝거나, 어두운 텍스트에 너무 어둡거나, 3:1 기준에 비해 흰색에 너무 가까운 경우. 해결책: L <= 0.55로 어둡게 하고 흰색 텍스트 사용, L >= 0.72로 밝게 하고 어두운 텍스트 사용, 또는 테두리와 함께 장식용으로 유지. - 색맹 검사
cvd으로. 기본, 성공, 오류 색상이 축소되는 경우(dE_OK < 0.10, 어떤 시뮬레이션에서든), 명도로 분리하고 아이콘과 레이블을 필수로 요구하세요. 색조만으로는 의미를 전달할 수 없기 때문입니다(WCAG 1.4.1). - APCA는 참고용. WCAG 3는 아직 대비 알고리즘을 채택하지 않았으므로(2026년 9월 작업 초안에 따르면 아직 미정), WCAG 2.2가 통과/실패를 결정합니다. APCA Lc를 경고로 보고하세요: 본문 텍스트가 |Lc| 75 미만이면 얇게 보이고(다크 모드에서 흔함), 15 미만이면 보이지 않게 됩니다.
- 상태 정의
states로, 수동으로 하지 마세요. Hover 및 active 비율은 팔레트에 따라 다릅니다: 평면 프리셋 비율은 측정된 45개 팔레트/프리셋 조합 중 37개에서 dL 0.03 미만(거의 보이지 않음)의 상태 단계를 하나 이상 남겼으며, hover 단계만으로도 26개에서 문제가 있었습니다.node $S states <palette> --preset standard --css는 믹스 비율과 방향(on-primary를 읽기 가능하게 유지하는 텍스트/배경 중 어느 쪽으로)을 해결하고, 각 상태의 대비를 검사하며,color-mix(in oklab, ...)변수를 생성합니다.generate --format css --states standard는 모든 모드에 추가합니다. 비활성화: 배경 쪽으로 혼합하고 비색상 신호를 추가합니다. 포커스: 2px 링, 오프셋 2px, 배경 대비 >= 3:1. 선택됨 및 방문함에는 비색상 신호가 필요합니다. - 비율 선택(아래 "비율 규칙" 참조)하고 전달 노트에 프리셋을 명시하세요.
- 출력 역할 테이블(헥스 + 정확한 OKLCH), 통과/실패 테이블, CSS 사용자 정의 속성, 선택적으로 Tailwind v4
@theme또는 DTCG JSON. 근거를 관례 또는 증거로 레이블 지정(references/evidence-and-conventions.md참조)하여 생성된 카피가 색상 심리학 민속학을 반복하지 않도록 하세요. - 보여주기. 데모 페이지(아래)를 제공하거나 구축하여 사용자가 견본 그리드가 아닌 실제 레이아웃에서 팔레트를 평가할 수 있도록 하세요.
역할 계약
모든 팔레트는 지원되는 각 모드에 대해 다음 역할을 정의합니다. 컴포넌트는 역할을 소비하며, 원시 헥스 값을 직접 사용하지 않습니다.
| 역할 | 목적 | 최소 기준 |
|---|---|---|
bg, surface, surface-2 | 캔버스, 카드, 올라온 패널 | 구별 가능 (OKLCH dL >= 약 0.03) |
border | 장식용 구분선 | 없음 |
border-strong | 입력 윤곽선, 컨트롤 | 3:1 (배경 기준, SC 1.4.11) |
text | 본문 | 4.5:1 (배경 및 표면 기준, 목표 7+) |
text-muted | 보조 텍스트 | 4.5:1 (배경 및 표면 기준) |
primary / on-primary | 주요 작업 채움 / 위의 텍스트 | 채움 3:1 (배경 기준), 링크 텍스트 4.5:1; 채움 위 텍스트 4.5:1 |
accent / on-accent | 선택적 두 번째 색조 | 의미를 전달한다면 primary와 동일 |
success warning error info | 상태 텍스트 및 아이콘 | 4.5:1 (배경 기준); 색상만으로 전달 금지 |
focus-ring | 키보드 포커스 | 3:1 (인접 색상 대비) |
램프에서 역할 매핑(50-950 스케일): 라이트: bg 50 또는 흰색, surface 흰색/50, surface-2 100, border 200, border-strong 500, text 900-950, text-muted 600, primary 600-700, on-primary 흰색, focus primary-600. 다크: bg 950(또는 900), surface 900, surface-2 800, border 800, border-strong 600, text 50-100, text-muted 400, primary 300-400, on-primary 950, focus primary-300. 이 매핑을 첫 번째 추측으로 간주하고 audit이 결정하도록 하세요.
엄격한 규칙 (WCAG 2.2 AA, AAA 요청 시)
- 텍스트 4.5:1; 큰 텍스트(>= 24px, 또는 >= 18.66px 굵게) 3:1; UI 컴포넌트 및 의미 있는 그래픽 3:1 (SC 1.4.11); AAA는 텍스트 7:1, 큰 텍스트 4.5:1.
- 장식용 테두리는 희미할 수 있지만, 필드의 유일한 신호인 입력 윤곽선은 3:1을 충족해야 합니다. 1.3:1 "우아한" 입력 테두리는 실패입니다.
- 색상만으로 의미를 전달해서는 안 됩니다. 본문 링크에 밑줄을 긋거나 주변 텍스트 대비 3:1과 hover/focus 신호를 제공하세요. 오류에는 아이콘과 메시지를, 차트 시리즈에는 직접 레이블이나 모양을 제공하세요.
- 틴트된 배경은 계산을 변경합니다. 흰색에 맞춰진 의미론적 색상은 따뜻한 종이 배경에서 약 4.4:1로 떨어집니다. 흰색이 아닌 실제 배경에서
audit을 실행하세요. - 그라데이션 및 사진의 대비는 최악의 지점(가장 밝고 어두운 영역)에서 유지되어야 하며, 그렇지 않으면 스크림을 추가하세요.
세부 사항, 공식, 색맹 안전 세트(Okabe-Ito) 및 APCA 임계값: references/accessibility.md.
OKLCH 작업
oklch(L C H)를 진실의 소스로 사용하세요.L은 지각된 명도(0-1)이므로, 동일한 L의 색상은 실제로 동일하게 밝게 보입니다. HSL에서는 50% 노란색과 50% 파란색이 크게 다릅니다. OKLCH에서 색조를 회전하면 명도가 유지되므로 하모니 오프셋이 OKLCH에서 작동하고 HSL에서는 작동하지 않는 이유입니다.- 매우 낮은 채도로 브랜드 색조를 중립에 틴트하세요: 흰색 근처에서 약 0.005-0.015, 어두운 색에서 0.01-0.045. 따뜻한 중립(색조 60-100)은 웰니스, 음식, 에디토리얼에 적합합니다. 차가운 중립(240-270)은 SaaS, 금융, 개발 도구에 적합합니다. 틴트된 중립 옆에 순수 회색이 섞이지 않도록 주의하세요.
- 램프 목표: L 0.985, 0.967, 0.928, 0.872, 0.707, 0.554, 0.446, 0.372, 0.279, 0.208, 0.129 (단계 50-950), 양쪽 끝에서 채도 테이퍼링. 채도를 줄여서 영역 매핑하고 클리핑하지 마세요. 브라우저는 조잡하게 클리핑합니다.
- 그라데이션:
in oklab또는in oklch로 보간하여 회색의 흐릿한 중간점을 피하세요. 거의 제로 채도의 전체 뷰포트 어두운 그라데이션(밴딩)을 피하거나 미세한 노이즈를 추가하세요. - 지원(2026년 후반):
oklch()는 2023년부터 Baseline;color-mix()는 2025년 11월부터 Widely Available; 상대 색상 구문은 Chrome 122+, Firefox 128+, Safari 18+;light-dark()는 2026년 11월 13일 Widely Available 도달.prefers-color-scheme과[data-theme]오버라이드가 있는 일반 사용자 정의 속성을 기본 출력으로 제공하고,light-dark()를 간결한 대안으로 제공하세요. 상대 색상 구문에서l은 0-1입니다.
결정 테이블: 요구사항에서 전략까지
| 요구사항 신호 | 중립 | 기본 | 강조 | 모드 | 목표 |
|---|---|---|---|---|---|
| 웰니스, 오가닉, 스파, 차 | 따뜻함, H 70-100, C 0.008-0.02 | 세이지/이끼/틸, C 0.05-0.10, L ~0.50 | 유사 또는 어스 컴플리먼트(테라코타, 클레이) | 라이트 | AA, 본문 7:1 권장 |
| 이커머스 | 중립/따뜻함, C <= 0.01 | 브랜드 | 다른 곳에서는 사용되지 않는 고립된 CTA 색조 | 라이트 | AA |
| SaaS / B2B | 차가움, H 250-270, C 0.01-0.04 | 블루/인디고/바이올렛 | 모노크롬 + 의미론적 | 라이트 + 다크 | AA |
| 개발 도구 | 차가움 또는 순수 회색 | 블루/바이올렛/그린, 어두운 L 0.70-0.80 | 모노; 코드에서만 구문 색상 | 다크 우선 + 라이트 | AA, APCA 확인 |
| 에이전시 / 포트폴리오 | 오프화이트 종이 또는 거의 검정 | 블랙/화이트 | 하나의 일렉트릭 강조색, 3:1 실패 시 테두리 포함 | 둘 중 하나 | AA |
| 금융 | 차가운 네이비 | 네이비/블루 | 손익을 +/-와 화살표로 표시 | 라이트 (+ 다크) | AA, 수치는 AAA |
| 건강 | 차가운 중립 | 틸/블루 | 차분한 그린 | 라이트 | AAA 본문 |
| 키즈 / 크리에이터 | 따뜻한 크림 | 채도 높은 바이올렛/블루 | 삼색, 각각 <= 10% 영역 | 라이트 | AA |
시작점: references/palettes.md (CSS, OKLCH 및 통과/실패 테이블이 포함된 15개 검증된 팔레트). 가장 가까운 것을 선택하고, 색조와 채도를 조정한 후 audit을 다시 실행하세요.
비율 규칙 및 프리셋
영역 분할은 예산일 뿐 법칙이 아닙니다: 60-30-10은 인테리어 디자인 관례로, 정확한 숫자에 대한 사용성 연구는 없지만, 작은 강조색 비율은 여기서 연구로 뒷받침된 한 가지 효과(CTA는 색조가 드물 때만 돋보임)를 보호합니다. 비율은 가시적인 배경 영역의 백분율입니다(텍스트 잉크는 계산되지 않음). ratio로 분할을 확인하고, 추정 대신 scripts/measure-area.js로 실제 페이지를 측정하세요.
| 프리셋 | 분할 n-s-a | 용도 |
|---|---|---|
classic | 60-30-10 | 이커머스 및 SaaS 마케팅, 일반 기본값 |
calm | 70-25-5 | 웰니스, 건강, 금융, 에디토리얼 |
dense-app | 80-17-3 | 대시보드, 관리자, 개발 도구(라이트 또는 다크) |
product-first | 80-15-5 | 사진이 색상을 전달하는 카탈로그; 하나의 고립된 CTA 색조 |
editorial | 70-27-3 | 브루탈리스트/에디토리얼: 테두리와 잉크가 역할 수행 |
dark-showcase | 70-22-8 | 하나의 생생한 강조색이 있는 다크 포트폴리오/에이전시 |
bold-brand | 50-30-20 | 크리에이터, 캠페인, 키즈: 강조색이 주도할 수 있음 |
규칙: 비율 합계 100 (FAIL); 중립이 가장 큰 비율, >= 45; 강조색은 프리셋 범위 내 유지(채도 높은 그라데이션과 브랜드 오버레이는 강조색으로 계산); 기본색이 강조 영역의 >= 70%를 차지하여 하나의 액션 색조가 주도하게 함; 의미론적 색상은 정지 상태에서 <= 2%; 다크 테마는 중립 >= 70 유지. 상태 프리셋(subtle 8/14/50, standard 12/20/60, strong 16/26/70 (hover/active/disabled의 최소 백분율), 틴트 8/10/14)은 단계가 보일 때까지 states에 의해 팔레트별로 상향 조정됩니다. 범위, 규칙 A1-A7 및 S1-S6, 방향 로직 및 측정 스니펫: references/proportions-and-states.md.
다크 모드
다크 테마는 두 번째 팔레트이지 역전이 아닙니다. 엔진은 측정 가능한 규칙(node $S dark ..., generate와 audit에서도 실행)을 적용하며, 나머지는 수동으로 적용할 구현 규칙입니다. 임계값과 수정 사항이 포함된 전체 테이블: references/dark-mode-rules.md.
측정됨 (FAIL은 차단됨; WARN은 명시된 이유 필요):
- D1 bg는 순수 검정이 아님: OKLCH L 0.13-0.24 (선언된 OLED 변형에 대해서만 실제
#000). - D2 텍스트는 순수 흰색이 아님: L 0.88-0.95. D3 텍스트/bg <= 17:1.
- D4 명도에 따른 고도: bg < surface < surface-2, 단계당 약 +0.04 L; 그림자는 어두운 곳에서 고도를 높이지 않음.
- D5 중립에 틴트, bg 채도 <= 0.045.
- D6 기본색은 밝은 채움(L >= 0.70)과 어두운 on-primary를 가지거나, 깊은 채움(L <= 0.58)과 흰색 on-primary를 가짐; 0.58-0.68 대역은 데드 존. 채움은 bg 및 surface에 대해 3:1 필요.
- D7 라이트 테마와 비교: 동일한 색조(10도 이내), 더 밝음, 채도가 더 높지 않음(10-30% 감소).
- D8 상태 색상은 다크에 맞게 재조정: bg 및 올라온 표면에서 4.5:1, 아이콘 및 텍스트 포함.
- D9 border-strong 3:1; 장식 테두리는 여전히 보임(dL >= 0.05). D11 포커스 링 3:1.
- D10 APCA 참고: 텍스트 |Lc| >= 75, muted >= 45 (목표 60); 다크 극성은 WCAG 2를 통과하는 얇은 텍스트를 드러냄.
수동: filter: invert 절대 사용 금지(N1); 어둡게 하는 대신 hover 시 밝게(N3); 알파 텍스트 없음(N4); 밝은 사진 어둡게 하고 라이트/모노 로고 변형 제공(N5); 작고 얇은 글꼴 사용 금지(N6); color-scheme 및 스킴별 theme-color 설정(N8); OS를 따르는 삼중 상태 토글 및 플래시 없음(N9); 어두운 표면에서 차트 색상 재확인(N10). 일반 시력 사용자에게는 라이트 모드가 더 잘 읽히고 일부 저시력 사용자에게는 다크 모드가 도움이 되므로 둘 다 제공하세요. 참조 다크 팔레트 및 토큰 아키텍처: references/dark-mode-and-tokens.md.
잡아야 할 안티패턴
크롬에 3개 이상의 채도 높은 색조; CTA 색조가 제목, 아이콘, 배지에 재사용됨; 동일 L의 채도 높은 보색(가장자리 진동); 유색 배경 위의 회색 텍스트(조정된 L에서 배경의 색조 사용); 4.5:1 미만의 밝은 회색-오프화이트 "미니멀" 텍스트; 흰색 텍스트가 있는 중간 L 강조색; 대체 없이 outline: none; 미세한 색조 이동으로만 구분되는 hover 및 active 상태(L을 0.05-0.10 변경); 활성화된 것처럼 보이는 비활성화 상태; 다크 모드에서 변경 없이 동일한 채도 높은 브랜드 색상 재사용; ...
[번역을 위해 잘림]