사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
소개▾
튜토리얼▾
핵심 개념▾
시스템 아키텍처▾

스타일링 기반

화면마다 색을 직접 적으면(여기는 #ff493b, 저기는 빨간 utility class), 브랜드를 바꾸거나 다크 테마를 더할 때 하나하나 찾아 고쳐야 합니다. Akan은 색에 용도로 이름을 붙이고, 모든 화면이 그 이름을 쓰게 해서 이 문제를 피합니다.
Akan은 Tailwind CSS와 시맨틱 디자인 토큰 계층, 그리고 akanjs/ui 프리미티브를 기본 스타일링 기반으로 사용합니다. 그래서 앱 화면은 모든 색을 하드코딩하지 않고 primary, background, warning, destructive 같은 의도로 말합니다. 두 도구는 일을 이렇게 나눕니다:
Tailwind CSS
구조와 레이아웃
레이아웃, 간격, 반응형 동작, 일회성 조합을 빠르게 적는 utility 언어입니다. Tailwind CSS
flex gap-4 p-4 md:grid-cols-2
토큰 + akanjs/ui
테마를 따라가는 색과 컴포넌트
테마를 따라가는 의미 기반 색 이름과 프리미티브(Button, Badge, Input, Field …)입니다.
bg-primary text-foreground <Button>
이 페이지에서 쓰는 말
semantic token
값이 아니라 역할로 이름 붙인 색입니다. primary, background, destructive 같은 이름입니다.
theme
모든 토큰에 대한 값 한 벌입니다. data-theme 속성이 어느 벌을 쓸지 고릅니다.
primitive
이미 토큰을 쓰도록 만들어진 akanjs/ui 컴포넌트입니다. Button, Input, Badge, Field 같은 것입니다.
custom property
--primary 같은 CSS 변수입니다. 토큰의 실체는 custom property입니다.
레이어가 함께 동작하는 방식
아래 계층을 딛고 올라가는 네 계층
아래에서부터 시맨틱 토큰, 토큰을 조합해 모양을 만드는 recipe, 동작을 더하는 컴포넌트, 컴포넌트를 조립한 화면 순서입니다. 화면의 모든 색은 결국 토큰에서 옵니다.
tokens
브랜드 결정을 primary, background, warning, destructive 같은 이름으로 바꾼 것입니다.
recipes
토큰 클래스를 조합해 이름 붙인 모양 하나로 만드는 함수입니다. buttonRecipe가 그 예입니다.
components
그 이름들을 쓰는 akanjs/ui 프리미티브(Button, Input, Badge)와 Tailwind utility class입니다.
screens
raw color와 spacing 규칙을 반복하지 않고, 컴포넌트를 조립해 만든 비즈니스 화면입니다.
토큰은 page/styles.css에 선언하고, 이 파일이 Tailwind와 Akan UI 스타일도 함께 import합니다. 그 파일은 아래 '테마 시스템 선언 방식'에서, recipe 계층은 UI 레시피 문서에서 다룹니다.

디자인 시스템을 먼저 설계

처음부터 따로 디자인한 페이지는 조금씩 어긋납니다. 버튼은 옆 페이지보다 약간 더 둥글고, border는 약간 더 옅어집니다. 그래서 앱의 기본 컴포넌트 스타일을 먼저 정의하고, 페이지는 그 컴포넌트를 조립하기만 하게 만드세요.
  • button, input, card, form, alert, tab, modal, navigation은 공유 클래스를 통해 같은 간격, radius, 텍스트 색, border, 상태 동작을 씁니다.
  • 비즈니스 페이지는 색과 간격을 다시 정의하지 않고 디자인 시스템을 조립합니다.
  • 가져온 모듈도 같은 Tailwind와 시맨틱 디자인 토큰을 쓰므로 일관되게 보입니다.
이렇게 만든 블록에는 색 값이 하나도 없고, 토큰 이름과 recipe만 있습니다:
테마를 바꾸면 블록 전체가 알아서 다시 칠해집니다. 안의 모든 클래스가 색이 아니라 토큰을 가리키기 때문입니다.

테마 시스템 선언 방식

컴포넌트는 bg-primary라고 한 번만 적습니다. 그것이 어떤 빨강인지는 앱 스타일 진입점이라는 파일 하나에서, 테마마다 한 번씩 정합니다. 선언은 네 단계입니다:
  1. Tailwind와 Akan UI 스타일을 import합니다.
  2. :root와 [data-theme] 아래에 테마별 원시 값을 CSS 변수로 정의합니다.
  3. @theme inline으로 그 변수들을 Tailwind 색 이름에 연결합니다.
  4. 테마 전환은 data-theme 속성만 바꾸면 됩니다. 다른 것은 바뀌지 않습니다.
apps/myapp/page/styles.css
글자가 올라가는 색에는 그 글자를 위한 -foreground 짝이 있습니다. bg-primary에는 text-primary-foreground가 짝이므로, primary 버튼 위 글자는 어느 테마에서나 잘 읽힙니다.

라이브러리 소유 토큰

테마를 따라가면 안 되는 색도 있습니다. 카카오 로그인 버튼은 라이트 테마에서도 다크 테마에서도 카카오 노랑입니다. 라이브러리의 컴포넌트에 이런 고정 색이 필요하면 라이브러리가 직접 선언합니다:
테마 토큰
테마를 따라갑니다
앱의 page/styles.css에 선언하고 @theme inline으로 연결합니다.
bg-primary
라이브러리 토큰
어느 테마에서나 고정
libs/<lib>/ui/tokens.css에 순수 custom property로 한 번 선언합니다.
bg-[var(--kakao)]
그 라이브러리에 닿는 앱은 이 파일을 자동으로, 자기 스타일시트보다 먼저 가져갑니다. 그래서 같은 변수를 둘 다 선언했다면 앱이 최종 결정권을 가집니다. 손으로 import할 것이 없고, 새 앱이 빠뜨릴 수도 없습니다.
libs/social/ui/tokens.css
libs/social/ui/KakaoButton.tsx

폰트 선언 방식

폰트는 루트 레이아웃에서 한 번 선언하고, 그다음부터는 다른 Tailwind 클래스처럼 씁니다. rootLayout() 체인의 .fonts() 단계에 배열을 넘기며, 항목마다 세 필드를 적습니다:
name
폰트 이름입니다. font-<name> 클래스가 됩니다. 예: font-pretendard.
paths
폰트 파일마다 항목 하나입니다. 파일 경로(src)와 그 파일이 맡는 weight를 적습니다.
default
폰트 클래스를 따로 주지 않았을 때 앱 전체가 쓰는 폰트입니다. 기본 폰트는 하나만 둘 수 있습니다.
apps/myapp/page/_layout.tsx
이제 각 이름이 클래스가 됩니다. 클래스를 주지 않은 글자는 기본 폰트, 여기서는 Pretendard를 씁니다:
Using font classes

MIT 라이선스 하에 배포되었습니다.

내 AI에 이 문서 연결하기

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js 모든 권리 보유.시스템 관리자bassman