컴포넌트 조합 규칙, 레이아웃 패턴, 스페이싱 시스템. 직각 철학과 토큰 기반 간격을 일관되게 적용하는 방법을 정의합니다.
Space Scale
gap: var(--space-3), padding: var(--space-6) — 토큰 기반 간격으로 일관된 리듬을 유지한다.
gap: 11px, padding: 19px — 임의의 픽셀 값은 시스템 리듬을 깨뜨린다.
허용 Radius — 이것만 사용 가능
기본 상태
모든 컴포넌트의 default. border-radius 생략 또는 0.
--radius-hover
:hover / :focus 상태에서만. 인터랙션 피드백 전용.
--radius-pill / --radius-round
GNAV 바, pill-tag, CTA 버튼, 아바타에만 허용.
| 토큰 | 값 | 허용 컴포넌트 | 금지 사례 |
|---|---|---|---|
| (없음 / 0) | 0px | 카드, 모달, 드롭다운, 인풋, 테이블, 배너 | — |
| --radius-hover | 3px | :hover, :focus 상태의 모든 인터랙티브 요소 | 기본(default) 상태에 적용 |
| --radius-pill | 100px | GNAV 활성 바, pill-tag 라벨, CTA 버튼 | 카드, 모달, 검색바, 인풋 필드 |
| --radius-round | 50% | 아바타, 상태 인디케이터 dot | 버튼, 카드, 배지 |
카드는 R=0, CTA 버튼에만 --radius-pill 적용.
카드에 border-radius: 12px, 버튼에 8px — 시스템 외 값 금지.
Pattern A — 작품 카드 (Asset Card)
이중섭 · 1956
황소
박수근 · 1963
나무와 두 여인
김환기 · 1971
어디서 무엇이 되어
| 구성 요소 | 위치 | 스페이싱 | 규칙 |
|---|---|---|---|
| Badge (상태) | 이미지 thumb 좌상단 오버레이 | top/left: var(--space-3) | position: absolute, 이미지 위에 띄운다 |
| Meta 텍스트 (작가·연도) | 제목 위 | margin-bottom: var(--space-1) | font-family: mono, text-muted, 제목보다 계층 낮게 |
| Card Title | Meta 아래 | margin-bottom: var(--space-3) | font-weight: 600, text 색상, 2줄 이상 말줄임 |
| Price + Action Button | 카드 하단 flex row | justify-content: space-between | 가격은 좌측, 버튼은 우측, border 없는 직각 버튼 |
Pattern B — 리스트 로우 (List Row)
| 구성 요소 | 스페이싱 | 규칙 |
|---|---|---|
| 테이블 헤더 | padding: var(--space-3) var(--space-4) | mono, uppercase, letter-spacing: wider, alpha-4 배경 |
| 데이터 로우 | padding: var(--space-4) | border-bottom: 1px solid border, hover 시 alpha-4 배경 + radius-hover |
| 인라인 Badge | padding: 2px var(--space-2) | R=0, 상태별 semantic 색상, mono 폰트 |
| 숫자 (금액) | — | font-family: mono, font-weight: 600, tabular-nums |
Layout A — 사이드바 + 메인 (Dealer ERP)
Layout B — 3컬럼 그리드 (Storyboard / Market)
gap: var(--grid-gap-md) = var(--space-6) · 768px 이하 2열 · 480px 이하 1열
Layout C — 2컬럼 (Detail / Doc)
gap: var(--space-8) · 768px 이하 단일 컬럼으로 전환
| 레이아웃 | 컬럼 | Gap 토큰 | 모바일 전환 |
|---|---|---|---|
| ERP Sidebar | 260px + 1fr | gap: 1px (구분선) | 768px 이하 사이드바 숨김, 드로어로 전환 |
| Card Grid 3col | repeat(3, 1fr) | var(--grid-gap-md) | 768px → 2col, 480px → 1col |
| Card Grid 4col | repeat(4, 1fr) | var(--grid-gap-md) | 960px → 3col, 768px → 2col, 480px → 1col |
| Doc Layout | 240px + 1fr | var(--space-8) | 768px 이하 단일 컬럼 |
| Section Container | max-width: 1280px | padding: 0 var(--content-px) | 모바일: var(--content-px-mobile) |
Section Label — mono, ls-ultra, red-brand
font-family: mono · font-size: text-11 · letter-spacing: ls-ultra · text-transform: uppercase
페이지 타이틀.
font-weight: 700 · ls-tightest · clamp(2rem, 5vw, 4rem) · accent .color: red-brand
섹션 타이틀
font-size: text-xl · font-weight: 700 · ls-tight
본문은 text-secondary 색상, 1.75 줄간격, letter-spacing normal로 가독성을 확보합니다. 최대 너비 52ch로 제한합니다.
font-size: text-base · color: text-secondary · line-height: 1.75 · max-width: 52ch
캡션 / 메타 텍스트 — 날짜, 작가명, 태그
font-family: mono · font-size: text-xs · color: text-caption · ls-wide
| 토큰 | 값 | 용도 |
|---|---|---|
| --ls-tightest | -0.04em | 히어로 타이틀, 대형 페이지 타이틀 |
| --ls-tight | -0.02em | 섹션 타이틀, 서브 헤드라인 |
| --ls-normal | 0 | 본문, 기본값 |
| --ls-wide | 0.04em | 캡션, 메타 텍스트, 작은 라벨 |
| --ls-wider | 0.08em | 버튼 텍스트, UI 라벨, 네비 아이템 |
| --ls-widest | 0.12em | 섹션 헤더 모노 라벨 |
| --ls-ultra | 0.18em | 히어로 라벨, 장식적 대문자 |
상태 매트릭스 — Button
Default
R = 0
Hover
R = 3px, shadow-sm
Focus
focus-ring
Active
opacity 0.85, scale 0.97
Disabled
alpha-8, cursor: not-allowed
| 상태 | 시각 변화 | 토큰 | transition |
|---|---|---|---|
| :hover | 배경색 darken, R 3px, 그림자 | --radius-hover, --shadow-sm | var(--dur-hover) var(--ease) |
| :focus-visible | focus ring (red 28%) | --focus-ring | var(--dur-fast) var(--ease) |
| :active | opacity 0.85, scale 0.97 | --dur-micro | var(--dur-micro) |
| :disabled | alpha-8 배경, text-muted, 포인터 없음 | --alpha-8, --text-muted | transition 없음 |
| 로딩 | opacity 0.6, 스피너 | --dur-medium (스피너 속도) | pointer-events: none |