색
--primary 위에 --primary-foreground 대비가 4.5:1 이상인가.
--muted-foreground가 라이트/다크 양쪽에서 읽히는가.
--border가 배경과 구분되는가.
앞의 여섯 장을 한 파일에 모으는 장이다.
globals.css하나를 완성한다.
프리셋Presetshadcn add 로 통째로 받아 적용할 수 있다.톤온톤Tone on Tone대비 검사Contrast Check출발점은 두 개다 — 브랜드 색과 중립색. 나머지는 그 둘에서 파생하거나 기본값에서 시작하되, 대비·상태색·제품 성격에 맞춰 검증한다.
먼저 브랜드 색을 oklch로 변환해 밝기·채도·색상 전체를 출발값으로 삼는다.
버튼 배경에서는 색상 인상을 유지하면서 밝기와 채도를 조절한다.
--primary: oklch(0.55 0.20 264);/* ↑ ↑ 채도 색상 */| 색상 각도 | 대략 |
|---|---|
25 | 빨강 |
60 | 주황 |
95 | 노랑 |
150 | 초록 |
195 | 청록 |
264 | 파랑 |
300 | 보라 |
hex 브랜드 색이 있다면 브라우저 개발자도구에서 색을 클릭해 oklch로 바꿔 보면 숫자가 나온다.
4장에서 본 그대로다.
현재 프리셋에서는 따뜻한 인상은 stone·taupe, 차가운 인상은 mist,
무채색은 neutral·zinc부터 비교한다. 미묘한 차이는 shadcn/create의 실제 화면으로 고른다.
라이트 값을 채운다
@import "tailwindcss";
:root { /* 브랜드 */ --primary: oklch(0.55 0.20 264); --primary-foreground: oklch(0.99 0 0);
/* 바탕과 표면 */ --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); --card: oklch(1 0 0); --card-foreground: oklch(0.145 0 0); --popover: oklch(1 0 0); --popover-foreground: oklch(0.145 0 0);
/* 보조 */ --secondary: oklch(0.97 0 0); --secondary-foreground: oklch(0.205 0 0); --muted: oklch(0.97 0 0); --muted-foreground: oklch(0.556 0 0); --accent: oklch(0.97 0 0); --accent-foreground: oklch(0.205 0 0);
/* 경고 */ --destructive: oklch(0.577 0.245 27);
/* 선 */ --border: oklch(0.922 0 0); --input: oklch(0.922 0 0); --ring: oklch(0.55 0.20 264); /* 포커스 링은 브랜드 색으로 */
/* 형태 */ --radius: 0.625rem;}다크 값을 채운다 — 밝기를 뒤집고 채도를 낮춘다
.dark { --primary: oklch(0.72 0.16 264); /* 밝게, 채도 ↓ */ --primary-foreground: oklch(0.20 0.04 264);
--background: oklch(0.145 0 0); /* 순수 검정 아님 */ --foreground: oklch(0.985 0 0); --card: oklch(0.205 0 0); /* 배경보다 밝게 = 떠 보임 */ --card-foreground: oklch(0.985 0 0); --popover: oklch(0.205 0 0); --popover-foreground: oklch(0.985 0 0);
--secondary: oklch(0.269 0 0); --secondary-foreground: oklch(0.985 0 0); --muted: oklch(0.269 0 0); --muted-foreground: oklch(0.708 0 0); --accent: oklch(0.269 0 0); --accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22);
--border: oklch(1 0 0 / 10%); /* 반투명 흰색이 자연스럽다 */ --input: oklch(1 0 0 / 15%); --ring: oklch(0.72 0.16 264);}Tailwind에 연결한다 — 빠뜨리면 클래스가 안 생긴다
@theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring);
--radius-sm: calc(var(--radius) * 0.6); --radius-md: calc(var(--radius) * 0.8); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) * 1.4); --radius-2xl: calc(var(--radius) * 1.8);
--font-sans: 'Pretendard Variable', system-ui, sans-serif; --font-mono: ui-monospace, Menlo, monospace;}바탕에 적용한다
<body className="bg-background text-foreground font-sans antialiased">토큰을 바꾸면 화면이 어떻게 달라지는지 다시 한 번 —
shadcn 공식 테마 편집기 — 웹에서 색을 조절하고 CSS를 복사한다
tweakcn — 커뮤니티 편집기. 미리 만든 테마가 많다
프리셋 받기 — 남이 만든 테마를 통째로 가져온다
pnpm dlx shadcn@latest add https://tweakcn.com/r/themes/<이름>.json처음에는 프리셋에서 시작해 브랜드 색만 바꾸는 편이 빠르다. 색 20개를 손으로 조화롭게 맞추는 건 생각보다 어렵다.
색
--primary 위에 --primary-foreground 대비가 4.5:1 이상인가.
--muted-foreground가 라이트/다크 양쪽에서 읽히는가.
--border가 배경과 구분되는가.
형태
--radius를 극단값(0, 2rem)으로 바꿔 봐도 화면이 안 깨지는가.
포커스 링이 잘리지 않는가 (overflow-hidden 주의).
글자
폰트 폴백이 있는가.
한글 본문에 break-keep이 걸려 있는가.
로딩 중 레이아웃이 덜컹거리지 않는가.
다크
새로고침해도 안 번쩍이는가. 카드가 배경과 구분되는가. 로고가 멀쩡한가.
브라우저 개발자도구에서 색 값 옆의 네모를 클릭하면 대비 비율이 바로 나온다.
AA 통과 표시가 있으면 본문 기준(4.5:1)을 넘은 것이다.
| 대상 | 필요한 대비 |
|---|---|
| 본문 글자 | 4.5:1 |
| 큰 글자 (약 18.7px 이상 굵게, 24px 이상 보통 굵기) | 3:1 |
| 테두리·아이콘 등 비텍스트 | 3:1 |
--muted-foreground가 가장 자주 걸린다. “흐리게” 하려다 안 읽히게 만드는 경우다.
--primary에 넣지 않는다. foreground와 한 쌍으로 실제 대비를 측정한다--card는 --background보다 밝게--border는 반투명 흰색(oklch(1 0 0 / 10%))이 자연스럽다--ring을 브랜드 색으로 두면 한 줄로 앱 인상이 바뀐다--muted-foreground 대비