<!-- canonical: https://docs.axelabs.ai/architecture/axe-ui -->
<!-- source: content/architecture/axe-ui.mdx -->

---
title: '@axe/ui 디자인 시스템'
description: AXE Labs 디자인 토큰 + 컴포넌트 라이브러리를 sync 스크립트 방식으로 소비. light/dark 토글, 5분 셋업, dogfood = axelabs.ai.
---

# @axe/ui 디자인 시스템

AXE Labs 의 단일 디자인 시스템 (`@axe/ui`). 색·간격·타이포·폰트 토큰 + 컴포넌트 클래스를 모든 React 소비자 (Blueprint · frame admin · hive admin · docs.axelabs.ai · axelabs.ai 회사 홈) 가 공유. npm registry 없이 **git+ssh 또는 sync 스크립트** 로 전파 ([D-axe-ui-1](/ops/decisions)).

> **본 페이지는 새 프로젝트에 적용하는 절차서**. 운영 중 변경 흐름은 [/ops/backlog](/ops/backlog) + [/ops/updates](/ops/updates).

## SSOT 경로

`/Users/axe/axelabs/` (github: `soohunkang/axelabs`) — 디자인 시스템 본가:

```
src/lib/
├── tokens/          colors · spacing · typography · fonts · index
└── styles/          reset · components
```

Canonical sync 스크립트: `/Users/axe/axelabs-docs/scripts/sync-axe-ui.mjs` — 그대로 복사 가능.

## 적용 절차 (Next.js 기준 5분)

### 1. sync 스크립트 복사

```bash
cp /Users/axe/axelabs-docs/scripts/sync-axe-ui.mjs PROJECT/scripts/
```

스크립트 안의 `axeLabsRoot` 가 `join(repoRoot, "..", "axelabs")` 로 잡혀 있음. 새 프로젝트가 `axelabs/` 와 같은 부모 디렉토리 (`/Users/axe/`) 에 있으면 그대로 OK. 다르면 그 한 줄만 수정.

### 2. `package.json` 의 `scripts` 에 4 줄 추가

```json
"sync-axe-ui":  "node scripts/sync-axe-ui.mjs",
"check-axe-ui": "node scripts/sync-axe-ui.mjs && git --no-pager diff --stat -- app/_axe-ui/ ':!app/_axe-ui/VERSION' && git checkout -- app/_axe-ui/",
"predev":       "node scripts/sync-axe-ui.mjs",
"prebuild":     "node scripts/sync-axe-ui.mjs"
```

### 3. 최초 sync 실행

```bash
npm run sync-axe-ui
# → app/_axe-ui/{tokens,styles,VERSION} 생성됨
```

### 4. `app/globals.css` 첫 부분에 import

Nextra/theme CSS **뒤에** 와야 override 됨:

```css
@import "./_axe-ui/tokens/colors.css";
@import "./_axe-ui/tokens/spacing.css";
@import "./_axe-ui/tokens/typography.css";
@import "./_axe-ui/tokens/fonts.css";
```

### 5. (선택) 컴포넌트 클래스도 사용

```css
@import "./_axe-ui/styles/reset.css";
@import "./_axe-ui/styles/components.css";
```

### 6. `app/_axe-ui/` 전체를 git commit

Docker/CI 빌드 안에서는 `axelabs/` 경로가 없음 — committed 산출물로 동작 (스크립트가 graceful skip).

## 테마 토글 — class · attribute 둘 다 지원

axelabs HEAD `ff6eb27` (2026-05-22) 이후 두 전략 모두 자동 매핑.

### A) class 전략 — next-themes 기본값

HTML 의 root element 에 `class="light"` 또는 `class="dark"`. Nextra docs 같이 next-themes 쓰면 추가 설정 불필요.

### B) attribute 전략 — root element 의 `data-theme` 속성

직접 토글 시:

```ts
useEffect(() => {
  document.documentElement.setAttribute("data-theme", mode);
}, [mode]);
```

둘 중 어느 쪽이든 토큰 정확히 매핑. OS `prefers-color-scheme` 도 명시적 light 선택을 덮어쓰지 않음.

## 검증

| 모드 | body bg | accent |
|---|---|---|
| light | `#f5f1e8` (cream) | `#821f3b` (claret) |
| dark | `#1a0610` (noir) | `#e3ff66` (neon) |

토글 시 즉시 반영. OS=dark + 사용자 "light" 선택해도 dark 로 안 어긋남.

## 최신 버전 체크 — 개발 중 SSOT 변경 감지

```bash
# 현재 sync 상태
cat app/_axe-ui/VERSION
# @axe/ui 0.1.0
# synced-at: 2026-05-22T...
# source: /Users/axe/axelabs
# source-sha: ff6eb27        ← axelabs HEAD
# source-lib-sha: ff6eb27    ← src/lib 마지막 변경 SHA
# source-lib-date: 2026-05-22 10:41:53 +0900

# 받을 변경 있나 (dry-run, 파일 안 건드림)
npm run check-axe-ui
# 빈 출력           = 최신
# "N files changed" = 받을 변경 있음

# axelabs 측에서 놓친 commit 목록
git -C /Users/axe/axelabs log SOURCE-LIB-SHA..HEAD -- src/lib/

# 실제로 받기
npm run sync-axe-ui && git add app/_axe-ui/ && git diff --staged
# 검토 후 commit: "sync(ui): @axe/ui bump to SHA"
# axe ship SERVICE
```

**자동**: `npm run dev` / `npm run build` 시 `predev`/`prebuild` hook 이 매번 sync 돌림. diff 가 생기면 그때 commit + ship 결정.

## 적용된 소비자

| 프로젝트 | 전략 | 비고 |
|---|---|---|
| `/Users/axe/axelabs-docs` | class | Nextra docs (본 페이지 포함) |
| `/Users/axe/axelabs/app/ui` | attribute | axelabs 메인 (디자인 시스템 자기 dogfood) |
| Blueprint | _예정_ | [B-axe-ui-blueprint-migrate](/ops/backlog) |
| frame admin / hive admin | _예정_ | 외부 customer rollout 전 |

## 관련 결정

- [D-axe-ui-1](/ops/decisions) — `@axe/ui` 단일 배포 채널 = git+ssh + axelabs.ai dogfood (Verdaccio / GitHub Packages / npm publish 모두 미사용 — 소비자 ≤3개 시점에서 부담만)
- [B-axelabs-ai-live](/ops/backlog) — axelabs.ai 도메인 라이브 배포 (production tag 핀 가능 시점 prereq)
- [B-axe-ui-v0.1-tag](/ops/backlog) — `v0.1.0` git tag (외부 소비자 stable 버전 시작점)

## 함정

| 함정 | 결과 | 회피 |
|---|---|---|
| sync 스크립트가 axelabs 경로 못 찾음 (Docker/CI) | sync graceful skip, committed `app/_axe-ui/` 사용 | 본 디렉토리 항상 commit + Dockerfile 의 `COPY . .` 에 포함 |
| Nextra theme CSS 가 토큰 override | 색 안 적용 | `@import` 순서 — `globals.css` 의 첫 부분 |
| Fontshare `@import` 의 `f[]=` drop (Blueprint 사례) | font 로드 실패 | `<link>` 방식 + Clash Display 패턴 일치 |
| OS `prefers-color-scheme` 이 사용자 선택 override | 토글 후 OS 따라 깜빡 | axelabs `ff6eb27` 이후 자동 회피 (사용자 명시 우선) |
