당근 디자인 시스템 Seed의 라이트 팔레트를 이 다크 블로그에 부어봤습니다. 토큰이 관리하는 면적은 변수 12개만 바꾸자 수정 없이 전환됐습니다.
깨진 곳은 네 군데 — 헤더·커버 스크림·본문 SVG·코드블록. 전부 토큰 밖의 하드코딩이었습니다. 로고 대비는 20.37:1에서 1.19:1로 무너졌습니다.
브랜드 색은 텍스트가 아니라 배경입니다. carrot #FF6600을 흰 바탕 텍스트로 쓰면 2.94:1 — Seed가 브랜드 색을 CTA 배경으로만 쓰는 이유가 숫자로 나옵니다.
당근의 디자인 시스템 Seed를 뜯어보다가 궁금해졌습니다. 남의 디자인 시스템 토큰을 내 사이트에 그대로 부으면 무슨 일이 생길까. 마침 이 블로그는 커스텀 테마를 CSS 변수 12개로 굴리고 있어서, 붓는 건 어렵지 않았습니다.
결론부터: 바뀐 곳보다 안 바뀐 곳이 더 많은 걸 알려줬습니다.
Seed는 어떻게 생겼나
seed-design.io의 CSS를 통째로 받아 커스텀 프로퍼티를 파싱했습니다. --seed- 접두 변수가 865개, var() 체인을 풀면 3계층이 나옵니다.
palette --seed-color-palette-carrot-600: #FF6600 ← 원색 램프
semantic --seed-color-bg-brand-solid: var(…carrot-600) ← 역할
component --seed-box-color: var(…fg-neutral) ← 부품
눈에 띄는 결정 세 가지.
| 결정 | 내용 |
|---|---|
| 팔레트 이름이 브랜드 | 램프 이름이 carrot — 100~1000 열 단계, 600이 canonical #FF6600 |
| 라이트/다크 이중 정의 | 같은 토큰명이 모드별로 다른 값 — 다크의 carrot-600은 #E65200으로 감쇠 |
| 상태 모델이 pressed | hover 토큰이 없고 전부 -pressed. pressed-scale 전용 이징 커브까지 토큰 |
hover 대신 pressed라는 건 이 시스템이 마우스보다 엄지를 먼저 생각한다는 뜻입니다. 데스크톱 블로그인 우리와 출발점이 다릅니다.
어떻게 부었나 — 워드프레스는 안 건드렸다
실험은 라이브를 건드리지 않는 방식으로 했습니다. 렌더된 글 상세 HTML을 파일로 뜨고, 그 사본의 <head> 끝에 스타일 한 블록만 주입했습니다. 되돌릴 것 자체가 없습니다.
:root{
--bg:#F7F8F9; /* ← gray-100 */
--surface:#FFFFFF; /* ← gray-00 */
--surface-2:#F3F4F5; /* ← gray-200 */
--line:#EEEFF1; /* ← gray-300 */
--fg:#1A1C20; /* ← gray-1000 */
--fg-sub:#5B606A;
--fg-faint:#868B94; /* ← gray-600 */
--r:12px; /* ← radius r3 */
}
.pill{border-color:#FF6600;color:#E14D00}
.card:active{transform:scale(.985)} /* pressed 흉내 */
우리 테마의 토큰 12개에 Seed 값을 매핑한 게 전부입니다. 폰트는 양쪽 다 Pretendard라 건드릴 게 없었습니다.
무엇이 따라왔나
본문 배경, 글자색, 표, 세 줄 요약 박스, 사이드바(목차·추천 글), 참고 문서 박스, 페이지네이션 — 전부 수정 0으로 라이트가 됐습니다. 값을 변수로 참조하던 면적은 값만 갈아끼우면 끝입니다.

무엇이 안 따라왔나 — 여기가 본론
깨진 곳은 네 군데였고, 네 곳 모두 원인이 같습니다. 값이 하드코딩돼 있어서 토큰 스왑이 닿지 않았습니다.
| 깨짐 | 원인 | 실측 |
|---|---|---|
| 로고 ‘aimake’ 실종 | 헤더 배경이 rgba(5,5,6,.86) 하드코딩 — 배경은 다크로 남고 로고 색만 토큰 따라 잉크로 바뀜 |
대비 20.37:1 → 1.19:1 |
| 커버가 검은 섬 | 스크림이 rgba(0,0,0,…) 하드코딩 + 커버 이미지가 다크 전제 자산 |
— |
| 본문 도식이 다크 섬 | SVG rect에 fill="#101012" — 콘텐츠에 박힌 색 (이 글에만 4개) |
— |
| 코드블록 다크 고정 | 하이라이트 플러그인의 다크 시트 — 테마 토큰 밖 | 라이트 테마의 다크 코드는 관행이라 허용 |
지난 글에서 전역 선택자가 새 컴포넌트를 망가뜨린 것과 같은 병의 다른 증상입니다. 그때는 “이름 없는 규칙이 대상을 안 가린다”였고, 이번엔 “이름 없는 값이 시스템을 안 따라온다”입니다.
Seed 값을 그대로 쓰면 안 되는 곳도 있었다
대비는 코드로 잰다는 원칙대로 스왑한 값들을 WCAG 공식으로 돌려봤습니다. 두 개가 걸렸습니다.
| 색 | Seed에서의 역할 | 흰 배경 대비 | 판정 |
|---|---|---|---|
#868B94 (gray-600) |
보조 텍스트 | 3.42:1 | 본문 보조로는 AA 미달 — 한 단 진한 #5B606A(6.31:1)로 올려 썼다 |
#FF6600 (carrot-600) |
브랜드 | 2.94:1 | 텍스트로는 미달. carrot-700(#E14D00)도 3.99:1 |
이건 Seed의 결함이 아니라 용법입니다. Seed는 carrot을 CTA의 배경으로 씁니다 — 주황 배경 위 흰 글자는 문제없습니다. 걸리는 건 “브랜드 색이니까 텍스트에도 쓰자”라고 가져가는 순간입니다. 브랜드 색은 배경이지 텍스트가 아닙니다.
그래서 뭘 가져오고 뭘 안 가져오나
| 항목 | 이유 | |
|---|---|---|
| 가져옴 | pressed 상태 모델 | 모바일 방문이 절반인데 hover만 설계해 왔다 |
| 가져옴 | 커버·도식도 토큰을 따르게 하는 리팩터 과제 | 이번에 깨진 네 곳이 그대로 할 일 목록 |
| 안 가져옴 | 라이트 팔레트 | 다크 에디토리얼이 이 블로그의 정체성 |
| 안 가져옴 | gray-600 보조 텍스트 | 우리 AA 기준(최악 배경 4.5:1) 미달 |
정리
- 토큰 시스템의 가치는 “바꿀 수 있다”가 아니라 “바꿨을 때 안 따라오는 게 뭔지 드러난다”는 것
- 깨진 네 곳은 전부 하드코딩 — 헤더 rgba, 커버 스크림, 콘텐츠 속 SVG 색, 플러그인 시트
- 남의 팔레트를 가져올 땐 대비부터 다시 잰다 — muted 3.42:1, 브랜드 2.94:1
- 브랜드 색은 배경이다 — 텍스트에 쓰는 순간 AA가 무너진다
- 실험은 렌더된 HTML 사본으로 — 라이브를 안 건드리면 원복도 필요 없다
디자인 시스템을 “적용”한다는 게 팔레트를 베끼는 일이 아니라는 걸 이번에 배웠습니다. 진짜 얻은 건 색이 아니라 경계선입니다 — 내 사이트에서 토큰이 지키는 영역과 못 지키는 영역이 어디서 갈리는지, 부어보기 전엔 몰랐습니다.