한국어
8장 토큰 아키텍처
토큰(token)은 디자인 값에 이름을 붙인 CSS 사용자 정의 속성(custom property)이며, Leysys의 색 토큰은 palette → ref → sys → semantic → component 다섯 계층을 거칩니다. 접두는 소유자를 드러내고, 다섯 가지 원칙이 중복과 흔들림을 막습니다.
왜 필요한가
같은 파란색을 화면마다 #0075ff로 적으면, 팔레트를 바꾸거나 다크 모드를 켜거나 브랜드 색을 바꿀 때 그 값을 쓴 모든 곳을 찾아 고쳐야 합니다. 값에 이름을 붙이면 바꿀 곳이 한 군데로 줄어듭니다.
이름에도 규칙이 필요합니다. 같은 값에 이름이 둘이거나 있을 법한 이름이 실제로는 없으면, 사람과 AI가 매번 다른 이름을 고릅니다. 토큰 아키텍처는 값을 바꾸는 곳과 있는 이름을 예측할 수 있게 만드는 장치입니다.
색 토큰 다섯 계층
EDS 소스에서 파란색이 주 버튼 배경과 강조 글자까지 가는 길은 다음과 같습니다.
css
/* palette: 팔레트 원본 값 */
--e-palette-color-blue-500: oklch(59.7% 0.2376 258); /* #0075ff */
/* ref: 팔레트와 무관한 50~950 단계, 팔레트 전환 지점 */
--e-ref-color-blue-500: var(--e-palette-color-blue-500);
/* sys: 역할 부여 */
--e-sys-color-primary-500: var(--e-ref-color-blue-500);
/* semantic: 용도 */
--e-text-primary-bold: var(--e-sys-color-primary-500);
/* component: 컴포넌트 전용 */
--e-button-primary-bold-bg: var(--e-sys-color-primary-500);| 계층 | 이름 | 하는 일 |
|---|---|---|
| palette | --e-palette-color-* | 팔레트 원본. 팔레트마다 원래 단계 이름을 둡니다 |
| ref | --e-ref-color-* | 모든 팔레트를 50~950으로 정규화합니다 |
| sys | --e-sys-color-* | primary, neutral 같은 역할을 붙입니다 |
| semantic | --e-bg-*, --e-text-*, --e-border-*, --e-icon-* | 배경·글자·테두리·아이콘의 용도를 붙입니다 |
| component | --e-button-* 등 | 한 컴포넌트가 쓰는 값입니다 |
- palette. 기본 Leysys 팔레트 외에 외부 디자인 시스템의 팔레트(
tailwind,gs,ant) 등이 있고, 단계 이름도 Leysys와tailwind는 50~950,gs는 010~110,ant는 1~11로 제각각입니다. - ref. 이 차이를 흡수합니다.
<html data-e-palette="gs">이면--e-ref-color-red-500이--e-palette-color-red-060을 가리킵니다. ref 뒤의 계층은 어떤 팔레트인지 모릅니다. - sys. 기본 역할 연결은 primary=blue, secondary=green, tertiary=yellow, destructive=red, success=green, warning=yellow, error=red, info=sky, neutral=gray입니다. 브랜드 주색 프리셋은 이 연결이 가리키는 색을 바꿉니다(12장).
- semantic과 component. semantic 이름은 속성이 먼저(
--e-{bg|border|text|icon}-…), component 이름은 소유자가 먼저 오고 상태가 마지막입니다(예:--e-button-primary-bold-bg-hover).
참조 규칙
- 참조는 화살표 방향으로만 흐릅니다. 뒤 계층이 앞 계층을 참조하고, 그 반대는 없습니다.
- 컴포넌트 CSS는 semantic이나 component 토큰만 쓰고, ref나 palette로 계층을 건너뛰어 바로 참조하지 않습니다.
- 팔레트 원본(
--e-palette-color-*)은 예외 없이 직접 참조하지 않습니다. 직접 참조하면 팔레트 전환이 깨집니다. 2026-10-04 KST 소스에서 palette를 참조하는 파일은 EDS와 MDS 각각의 ref 파일 하나뿐이었습니다. - 컴포넌트 CSS가 ref를 직접 쓰는 예외는 둘입니다. 하나는 색 이름 자체가 공개 API인 컴포넌트(현재
e-button-supplement.css)이고, 다른 하나는 흰색·검정·투명 같은 물리 상수입니다.
첫 번째 예외에 원칙이 담겨 있습니다. 계층 규칙은 모든 계층을 반드시 거치라는 뜻이 아니라, 의미 있는 계층만 거치라는 뜻입니다. 「파랑」 같은 직접 색에는 역할(sys)이 없습니다. 없는 계층을 만들어 거치게 하면 17개 색 × 11단계만큼 같은 값의 토큰이 늘어날 뿐입니다.
MDS와 Print DS
MDS도 같은 길을 자기 접두로 갑니다. 다만 역할 계층의 이름은 Nuxt UI 어휘인 --m-color-{역할}-{단계}입니다 (예: --m-color-primary-500). Print DS의 색은 9장의 Leysys 모델이 아니라 별도 인쇄 계약을 따릅니다.
접두와 유틸리티
토큰 접두는 소유자를 나타냅니다. EDS는 --e-*, MDS는 --m-*, Print DS는 --print-*, Markdown DS는 --md-*입니다. 3.0부터 EDS의 접두 없는 호환 이름은 게시하지 않습니다.
유틸리티 클래스는 다음 셋 중 정확히 하나로 분류합니다.
| 분류 | 접두 | 예 | 기준 |
|---|---|---|---|
| pure | 없음 | text-md, grid-cols-max4-* | Tailwind 어휘의 빈자리를 채움. DS 토큰을 참조하지 않음 |
| specialized | e-, m- | e-bg-neutral-minimal, e-text-neutral-bold | DS의 토큰이나 의미를 소유함 |
| external | 없음 | material-symbols-outlined, is-filled | 외부 제공자가 정한 철자를 보존함 |
시맨틱 유틸리티는 토큰과 같은 이름에 진영 접두를 붙입니다.
css
.e-bg-neutral-minimal {
background-color: var(--e-bg-neutral-minimal);
}Tailwind 색 클래스(bg-red-500)는 외부 표준 어휘로 그대로 쓰고, Leysys 소스에서 다시 정의하지 않습니다.
토큰 원칙 다섯 가지
- 스케일 전체 보존. 크기 단계가 있는 컴포넌트는 지금 쓰는 곳이 없는 단계까지 토큰을 모두 정의합니다 (예:
--e-button-radius-{xs..3xl}). 빈 단계가 있으면 「이 조합도 있겠지」 하고 쓰다가 정의되지 않은 값을 참조하게 됩니다. 단, 컴포넌트가 실제로 가진 크기 변형에 한합니다. - 중복 토큰 금지. 같은 값을 두 이름으로 정의하지 않습니다. 예외는 의도된 어휘 별칭(alias)이며, 어휘를 나누려는 의도가 적혀 있고, 값이 100% 같고, 별칭이 한 방향이라는 세 조건을 모두 갖춰야 합니다. 예를 들어 Leysys 컴포넌트는 기본 글자 단계를
md, Tailwind는base라 부릅니다. 그래서 컴포넌트 토큰--e-text-md(1rem)와 별개로, pure 유틸리티.text-md가 Tailwind의--text-base를 읽습니다. 여러 컴포넌트가 같은 크기 체계에서 같은 값을 갖는 것은 중복이 아닙니다. - Tailwind와 역할 분리. 간격(padding, margin, gap)은 Tailwind 유틸리티가 맡고, 같은 역할의 CSS 변수를 따로 만들지 않습니다. Leysys도 한때 「가까움」과 「섹션」을 뜻하는 간격 축(
--spacing-proximity-*,--spacing-section-*)을 만들었다가, Tailwind 간격 어휘와 두 체계가 공존해 AI가 헷갈리자 2026-05-27 KST에 149곳에서 모두 걷어냈습니다. - 방향별 토큰 지양.
--*-top-sm처럼 위·오른쪽·아래·왼쪽으로 나눈 토큰을 만들지 않습니다. 필요하면 논리 방향inline과block만 씁니다(예:--e-button-padding-inline-md). - 컴포넌트 CSS는 단일 토큰 참조.
e-button.css의 모서리 선언은border-radius: var(--e-button-radius)한 곳뿐입니다. 크기 클래스(.e-button-sm등)는 모서리와 색에 관여하지 않습니다. 단계별 분류 토큰 (--e-button-radius-sm등)은 정리용으로 두고 컴포넌트 CSS에서 참조하지 않습니다. 간격만은 역할별로 여러 토큰을 허용합니다(컴포넌트당 3개 이하 권장). 크기에 비례하는 간격은 단계별로 두고 (--e-tabs-trigger-gap-sm·-md·-lg= 4·8·8px), 비례하지 않으면 하나로 둡니다(--e-toolbar-gap= 2px).
다크 모드
다크 모드는 <html data-theme="dark">로 켭니다. 그러면 같은 이름의 semantic·component 토큰이 다른 단계를 가리키도록 다시 연결됩니다(color-semantic-dark.css, color-component-dark.css). 함께 선언하는 color-scheme: dark는 브라우저 기본 요소도 어두운 모양을 따르게 합니다.
| 토큰 | 라이트 | 다크 |
|---|---|---|
--e-bg-neutral-minimal | 흰색 | neutral-950 |
--e-text-neutral-bold | neutral-800 | neutral-50 |
--e-text-primary-bold | primary-500 | primary-300 |
컴포넌트는 이 토큰만 쓰므로 다크 모드용 코드를 따로 갖지 않습니다. 반대로 고정 단계 토큰을 쓰면 깨집니다. MDS의 primary 채움 버튼은 배경에 고정 단계를, 글자에 다크에서 어두워지는 반전 색을 써서 다크 모드 대비가 3.62:1로 떨어졌습니다. 배경을 다크에서 한 단계 밝아지는 대표 토큰 --m-primary로 바꾸자 5.37:1이 되었습니다. MDS도 같은 data-theme 속성을 쓰고, Print DS에는 다크 모드가 없습니다.
실제 예: 팔레트 전환
html
<html data-e-palette="tailwind" data-e-neutral="zinc">이 한 줄은 ref 계층의 연결만 바꿉니다. sys, semantic, component 토큰과 컴포넌트 CSS는 그대로입니다. EDS의 기본 무채색은 주색 파랑의 틴트 무채색(blue-gray)이며, data-e-neutral="pure-gray"로 순수 회색을 고를 수 있습니다.
경계와 예외
- 외부 변수에는 접두를 붙이지 않습니다. Tailwind 테마 변수(
--text-base)와 Reka UI가 실행 중에 주입하는 변수(--reka-select-trigger-width)는 접두가 없습니다. 여기에--e-를 붙이면 해석되지 않습니다. - Print DS의 색 역할. 본문, 표, 테두리는 컬러 출력에서도 순수 무채색을 씁니다. 일반 문서의 유채색은
--print-accent-*와--print-status-*역할을 거쳐 씁니다. 흑백 출력(data-print-color="mono")이 이 역할을 무채색으로 바꾸기 때문입니다. 브랜드 지정색, 법정 지정색, 색 자체가 데이터인 차트만 제품의 결정 기록을 거쳐 직접 색을 쓰며, 흑백 출력이 이 직접 색까지 바꾼다고 보장하지는 않습니다.
정리
- 색 토큰은 palette → ref → sys → semantic → component 순서이며, 팔레트 원본은 ref만 참조합니다.
- 팔레트 전환은 ref, 역할 연결은 sys, 다크 모드는 semantic·component 연결을 바꿉니다. 컴포넌트 CSS는 그대로입니다.
- 접두가 소유자를 밝힙니다. 토큰은
--e-*·--m-*·--print-*이고, 유틸리티는 pure·specialized·external 중 하나입니다. - 다섯 원칙은 스케일 보존, 중복 금지, Tailwind와 역할 분리, 논리 방향만 사용, 단일 토큰 참조입니다.
정본
leysys-designdocs/specs/CSS-ARCHITECTURE.md— 토큰 위계, 토큰 원칙, 다크 모드leysys-designdocs/specs/NAMING-CONVENTION.md— 계층 접두, 토큰 이름 문법, 유틸리티 분류leysys-designdocs/decisions/DS-3.0-SCOPE-AND-SUPPORT-POLICY-2026-09-28.md— 5계층 명칭과 3.0 호환 이름 제거leysys-designdocs/decisions/COLOR-REF-LAYER-DIRECT-REFERENCE-EXCEPTION-2026-06-10.md— ref 직접 참조 예외leysys-designdocs/decisions/UTILITY-TRIAD-CLASSIFICATION-2026-08-04.md— 유틸리티 세 분류leysys-designdocs/decisions/SPACING-SEMANTIC-AXIS-RETIRE-2026-05-27.md— 의미 간격 축 폐지leysys-designdocs/decisions/TEXT-MD-BASE-VOCABULARY-SEPARATION-2026-05-21.md—md와base어휘 별칭leysys-designdocs/decisions/MDS-SOLID-FILL-DARK-REPRESENTATIVE-2026-06-15.md— MDS 채움 버튼의 다크 모드 대표 토큰